So what I’m trying to do is create a polar chart using plotly. However, it needs to look similar to a pie chart, where each label
is given a slice of the circle. Currently the polar chart works fine, if I divide the circle into equal slices. But, when I try to give them a slice corresponding to the weights
it doesn’t work out too well, as it tends to overlap or leave spaces between each slice. This is mainly due to the Theta.
Can someone please explain where I’ve gone wrong?
Ratings
- Max value is 5, Min value is 1. This is used to determine the length of the slice in the polar chart.
Weights
- Max value is 100, Min value is 1. This is used to determine the width of the slice in the polar chart.
Labels
- To identify each slice.
When equally splitting the circle
import plotly.graph_objects as go
import plotly.express as px
ratings = [3, 2, 5, 1, 2]
weights = [65, 79, 81, 98, 58]
labels = ["Strength", "Intelligence", "Dexterity", "Wisdom", "Stealth"]
def make_barpolar(ratings, weights, labels=None, colors=None, layout_options = None, **fig_kwargs):
# infer slice angles
num_slices = len(weights)
theta = [(i) * 360 / num_slices for i in range(0, num_slices)]
width = [360 / num_slices for _ in range(num_slices)]
# optionally infer colors
if colors is None:
color_seq = px.colors.qualitative.Safe
color_indices = range(0, len(color_seq), len(color_seq) // num_slices)
colors = [color_seq[i] for i in color_indices]
if layout_options is None:
layout_options = {}
if labels is None:
labels = ["" for _ in range(num_slices)]
layout_options["showlegend"] = False
# make figure
barpolar_plots = [go.Barpolar(r=[r], theta=[t], width=[w], name=n, marker_color=[c], **fig_kwargs)
for r, t, w, n, c in zip(ratings, theta, width, labels, colors)]
fig = go.Figure(barpolar_plots)
# additional layout parameters
fig.update_layout(**layout_options)
return fig
layout_options = {"title": "My Stats",
"title_font_size": 24,
"title_x": 0.5,
"legend_x": 0.85,
"legend_y": 0.5,
"polar_radialaxis_ticks": "",
"polar_radialaxis_showticklabels": False,
"polar_radialaxis_range": [0, max(ratings)],
"polar_angularaxis_ticks": "",
"polar_angularaxis_showticklabels": False}
fig = make_barpolar(ratings, weights, labels, layout_options=layout_options, opacity = 0.7)
fig.show()
When using the weights
to calculate the width and theta
import plotly.graph_objects as go
import plotly.express as px
ratings = [3, 2, 5, 1, 2]
weights = [65, 79, 81, 98, 38]
labels = ["Strength", "Intelligence", "Dexterity", "Wisdom", "Stealth"]
def make_barpolar(ratings, weights, labels=None, colors=None, layout_options = None, **fig_kwargs):
# infer slice angles
angles = [(weight / sum(weights) * 360) for weight in weights]
theta = []
num_slices = len(ratings)
theta = []
for index, angle in enumerate(angles):
if index < len(angles)-1:
if index == 0:
theta.append(0)
theta.append(theta[index] + angle)
width = angles
# optionally infer colors
if colors is None:
color_seq = px.colors.qualitative.Safe
color_indices = range(0, len(color_seq), len(color_seq) // num_slices)
colors = [color_seq[i] for i in color_indices]
if layout_options is None:
layout_options = {}
if labels is None:
labels = ["" for _ in range(num_slices)]
layout_options["showlegend"] = False
# make figure
barpolar_plots = [go.Barpolar(r=[r], theta=[t], width=[w], name=n, marker_color=[c], **fig_kwargs)
for r, t, w, n, c in zip(ratings, theta, width, labels, colors)]
fig = go.Figure(barpolar_plots)
# additional layout parameters
fig.update_layout(**layout_options)
return fig
layout_options = {"title": "My Stats",
"title_font_size": 24,
"title_x": 0.5,
"legend_x": 0.85,
"legend_y": 0.5,
"polar_radialaxis_ticks": "",
"polar_radialaxis_showticklabels": False,
"polar_radialaxis_range": [0, max(ratings)],
"polar_angularaxis_ticks": "",
"polar_angularaxis_showticklabels": False}
fig = make_barpolar(ratings, weights, labels, layout_options=layout_options, opacity = 0.7)
fig.show()