Radial Bar Chart (3 seperated bars)

Greetings Plotly community,

I was able to create a radial bar chart like the one below:
image

But what I’m trying to do, is a radial bar chart similar to this one (3 seperated bars):

This chart is supported by R library called ggplot2, so i was wondering if Plotly provide the ability to create similar chart?

Any help is truly appreciated,
Thanks.

@JayR7 ,
Calling

help(go.layout.Polar.barmode)
   Determines how bars at the same location coordinate are
   displayed on the graph. With "stack", the bars are stacked on
   top of one another With "overlay", the bars are plotted over
   one another, you might need to reduce "opacity" to see multiple
   bars.
   
   The 'barmode' property is an enumeration that may be specified as:
     - One of the following enumeration values:
           ['stack', 'overlay']

we are noticing that it doesn’t display barmode="group", similar to cartesian case.
But I deduced an algorithm to plot grouped polar bars, according to the number of categories/groups and the bar numbers in each group:

import plotly.graph_objects as go
categories=10
nbar_group=5 #number of bars in a group
step = 360/categories
small_step=step/(nbar_group+1)
theta = [0.5*(2*k-1)*step+small_step*(j+1)  for k in range(categories) for j in range(nbar_group)]
r = [12, 10, 7, 5, 2]*categories 
tickvals=[k*step for k in range(categories)]
ticktext=["C", "B", "A", "J", "I", "H", "G", "F", "E", "D"]

fig=go.Figure(go.Barpolar(r=r, theta=theta, marker_color=r, marker_colorscale="Blues",
                           marker_colorbar_thickness=23))
fig.update_layout(width=500, polar=dict(angularaxis=dict(tickvals=tickvals, ticktext=ticktext)))

barpolar-group

2 Likes

Thanks a lot @empet for your prompt response!

It really helped! and i’m very close to the final touch, thanks goes to you.

The only issue left, is that it doesn’t recognize the groups, only recognizing one.
Here’s my code below, it’s similar to yours.

categories=10
values=df_timimg_merged['value']
nbar_group=3 #number of bars in a group
step = 360/categories#36
small_step=step/(nbar_group+1)#9
theta = [0.5*(2*k-1)*step+small_step*(j+1)  for k in range(categories) for j in range(nbar_group)]
r = values
tickvals=[k*step for k in range(categories)]
ticktext=[5,4,3,2,1,12,11,10,9,8]

fig=go.Figure(go.Barpolar(r=r, theta=theta, marker_color=r, marker_colorscale="Blues",
                           marker_colorbar_thickness=23))
    
fig.update_layout(width=500, polar=dict(angularaxis=dict(tickvals=tickvals, ticktext=ticktext)))

image

And here’s a snapshot of my data:
image

For each hour, i have 3 groups (3 bars) each group supposed to be with diff color.

Could you post the list of values? The len(r) must be equal to len(theta).
r = [val1, val2, val3, v1, v2, v3, u1, u2, u3, … x1, x2, x3]
i.e. for each group you must give the three values consecutively.

So you mean r values supposed to have the same values for each group?

And regarding r values (value column):

hours group value
0 8 agent_name 0.00000
1 8 waiting 1.00000
2 8 counts 7.00000
3 9 agent_name 3.00000
4 9 waiting 1.53846
5 9 counts 13.00000
6 10 agent_name 2.00000
7 10 waiting 1.27778
8 10 counts 18.00000
9 11 agent_name 1.00000
10 11 waiting 0.93333
11 11 counts 30.00000
12 12 waiting 1.65517
13 12 counts 29.00000
14 12 agent_name 1.00000
15 1 counts 23.00000
16 1 agent_name 1.00000
17 1 waiting 0.73913
18 2 counts 32.00000
19 2 agent_name 0.00000
20 2 waiting 0.65625
21 3 counts 22.00000
22 3 agent_name 3.00000
23 3 waiting 0.45455
24 4 waiting 0.80000
25 4 counts 10.00000
26 4 agent_name 1.00000
27 5 counts 16.00000
28 5 agent_name 6.00000
29 5 waiting 1.00000

Theta & r have the same length, 30.

@JayR7
The go.Barpolar works well, when data have r of the same order of magnitude. But in your case min(r)=0, and max(r)=30. Look at the first graph you posted here, and notice how small are the red bars compared to the light blue ones. When we draw them in the group version, only the ones that are blue in your figure are shown, but not those red.
I think that here the bars of small r and theta are lost because they are not overlapped as in your original plot, but each one is assigned a theta value. Most likely the algorithm implemented in plotly.js neglects the bars of small r and/theta.

LE: With matplotlib:

import numpy as np
import matplotlib.pyplot as plt
ax = plt.subplot(projection='polar')
ax.bar(theta, r, width=np.pi/20, bottom=0.0)
plt.show()

it looks similar, and moreover we can see the small bars, which in Plotly are not visible.
It’s a long time since I haven’t worked with mpl and I dont know how to use different colors for bars or a colormap. But the plot illustrates the essential: r-data do not have the same order of magnitude, and this explains why it looks different and not as we are expecting.
mpl-barpolar

Ok, I see… I was actually having doubts about the gaps between the data.

Its clear to me now, I might do some data normalization, hopefully it would help.

One last question please, i’m looking for px.bar_polar argument that’s responsible on adjusting the bars angle? I would like to minimize the width of the angle in the first image of my first post, to be like the one underneath it. Is it possible?

@JayR7
If fig=px.bar_polar()
and, let us say you want to set the bar width in the trace wuth name="mybarp", then

fig.update_traces(selector=dict(name="mybarp"), marker_width=array_of_widths_or_single_value)

changes the bar width in your trace.

Thanks a lot @empet, that was a very informative thread.
We do really appreciate you for sharing knowledge over the years!

Have a good day :wave:

1 Like