I’ve scowled the internet and tried various ways to create a subplot with three scatterpolar plots and three bar plots.
I’ve come down to this…
Let’s say I have three dataframes that I filtered from another database to gives me data for students and how much they completed each category. We’ll use this one as an example of all three:
platform_df = pd.DataFrame({'category': ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J'],
'%' : ["55","5","100","95","45","99","75","64","93","10"],
'platform' : ['primer','primer','primer','primer','primer','primer','primer','primer', 'primer', 'primer']})
I have a function that allows me to create a bar plot with the color variations of the bars based on the grades:
grade_colors = RangeDict({
range(0,60): 'crimson',
range(60,70): '#E34363',
range(70,80): '#FFB733',
range(80,90): '#29CC92',
range(90,101): '#339933'})
def student_category_bar_grade(df,platform):
df_filtered = df[df['platform']==platform].sort_values(by='Category',ascending=True)
fig = go.Figure()
for completed,sdf in df_filtered.groupby('completed'):
print(sdf)
color = grade_colors[completed]
fig.add_traces(
go.Bar(x=sdf['Category'],
y=sdf['completed'],
customdata=sdf['platform'],
name=str(completed)+" %",
marker={'color': color},
hovertemplate="<br>".join([
"Platform: %{customdata}",
"Category: %{x}",
]),
)
)
# Change the bar mode
fig.update_layout(title_text=platform)
fig.update_layout(barmode='group'
)
fig.update_layout(showlegend=False)
fig.update_layout(
title_x=0.5,
title_font_size=26,
title_font_family="Copperplate",
title_font_color="teal",
)
return fig
def student_topic_scatter_polar_graph(df,platform):
df_filtered = df[df['platform']==platform].sort_values(by='topic',ascending=True)
color = colors[platform]
print(color)
fig = go.Scatterpolar(
r=df_filtered.completed,
theta=df_filtered.topic,
fill='toself',
name="%s - Focused Topics"%platform,
fillcolor=color,
opacity=0.6,
line=dict(color=color)
)
and I have a function for creating scatterpolar plots. Let’s use the same dataframe as an example:
def student_topic_scatter_polar_graph(df,platform):
df_filtered = df[df['platform']==platform].sort_values(by='topic',ascending=True)
color = colors[platform]
print(color)
fig = go.Scatterpolar(
r=df_filtered.completed,
theta=df_filtered.category,
fill='toself',
name="%s - Focused Categories"%platform,
fillcolor=color,
opacity=0.6,
line=dict(color=color)
)
fig.update_layout(
template=None,
polar = dict(
radialaxis = dict(range=[0, 100],
visible=True,)
),
title="%s - Focused Categories"%platform)
return fig
primer_category_bar_fig = student_category_bar_grade(students_category_earned,'Primer')
primer_topic_scatter_polar_fig = student_topic_scatter_polar_graph(students_category_earned,'Primer')
I started building the subplots like so:
#create subplot
student_subplot = make_subplots(rows=2, cols=3,
specs=[
[{'type': 'scatterpolar'},{'type': 'scatterpolar'},{'type': 'scatterpolar'}],
[{'type': 'bar'},{'type': 'bar'},{'type': 'bar'}]])
figure1_traces = []
figure2_traces = []
figure3_traces = []
# combine the figs to the subplot
for trace in range(len(primer_category_bar_fig ["data"])):
figure1_traces.append(primer_category_bar_fig ["data"][trace])
for trace in range(len(primer_category_bar_fig ["data"])):
figure2_traces.append(primer_category_bar_fig ["data"][trace])
for trace in range(len(primer_category_bar_fig ["data"])):
figure3_traces.append(primer_category_bar_fig ["data"][trace])
student_subplot.add_trace(primer_topic_scatter_polar_fig,row=1,col=1)
student_subplot.add_trace(primer_topic_scatter_polar_fig,row=1,col=2)
student_subplot.add_trace(primer_topic_scatter_polar_fig,row=1,col=3)
student_subplot.add_trace(figure1_traces,row=2,col=1)
student_subplot.add_trace(figure2_traces,row=2,col=2)
student_subplot.add_trace(figure3_traces,row=2,col=3)
dbc.CardBody([
html.H4("students stats", className="card-title"),
dcc.Graph(figure=student_subplot),
])
But I can’t figure out what I’m doing wrong.