Python Plotly Polar Chart Slice Alignment

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()

good

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()

bad