Hi @jarelan
I did not fully understand how or why you wanted to use subplots so I changed your layout. Basically each figure is separated from each other. As you are using dash anyway I thought, I could do this
from dash import Dash, dcc, html, Output, Input
from plotly import graph_objects as go
import dash_bootstrap_components as dbc
import pandas as pd
pd.set_option('display.max_rows', None)
Dash(assets_ignore='.*ignored.*')
app = Dash(__name__, external_stylesheets=[dbc.themes.BOOTSTRAP])
# neglect false warnings
pd.options.mode.chained_assignment = None # default='warn'
# color dictionary
class RangeDict(dict):
def __getitem__(self, item):
if not isinstance(item, range):
for key in self:
if item in key:
return self[key]
raise KeyError(item)
else:
return super().__getitem__(item)
grade_colors = RangeDict({
range(0, 60): 'crimson',
range(60, 70): '#E34363',
range(70, 80): '#FFB733',
range(80, 90): '#29CC92',
range(90, 101): '#339933'})
colors = {
'background': '#111111',
'text': 'teal',
"0": "silver",
"1": "#FBEC5D",
"5": "#50C878",
"10": "#40E0D0",
"15": "#A23D60",
0: "silver",
1: "#FBEC5D",
5: "#50C878",
10: "#40E0D0",
15: "#A23D60",
'Linux': '#50C878',
'Windows': '#66D3F4',
'Primer': '#FFD700',
}
# pandas dataframe used for plots
students_category_earned = pd.DataFrame({
'Category': ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'A', 'A', 'B', 'B', 'C', 'C'],
'completed': [55, 55, 100, 95, 45, 99, 75, 64, 93, 10, 15, 55, 45, 78, 98, 33],
'platform': ['primer', 'primer', 'primer', 'primer', 'primer', 'primer', 'primer', 'primer',
'primer', 'primer', 'Linux', 'Windows', 'Linux', 'Windows', 'Linux', 'Windows']
})
print(students_category_earned)
print(" - " * 9)
print(students_category_earned)
students_topics_earned = pd.DataFrame({
'topic': ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'A', 'A', 'B', 'B', 'C', 'C'],
'completed': [55, 55, 100, 95, 45, 99, 75, 64, 93, 10, 15, 55, 45, 78, 98, 33],
'platform': ['primer', 'primer', 'primer', 'primer', 'primer', 'primer', 'primer', 'primer',
'primer', 'primer', 'Linux', 'Windows', 'Linux', 'Windows', 'Linux', 'Windows']
})
print("students_topics_earned")
print("-" * 9)
print(students_topics_earned)
# functions to creating the plots
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'):
color = grade_colors[completed]
fig.add_trace(
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',
plot_bgcolor=colors['background'],
paper_bgcolor=colors['background'],
font_color=colors['text']
)
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]
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)
)
return go.Figure(fig)
# ------------------------------------------------MAIN CHANGES
# create a grid of dcc.Graph(), rows x columns
rows = 2
columns = 3
content = []
component_ids = []
for r in range(rows):
row_content = []
for c in range(columns):
component_id = f'row{r}_col{c}'
component_ids.append(component_id)
row_content.append(
dbc.Col(
dbc.Card(
children=dcc.Graph(id=component_id),
)
)
)
dbc_rows = dbc.Row(
id=f'row{r}',
children=row_content
)
content.append(dbc_rows)
# app layout
app.layout = html.Div(
[
html.H4("Student Name"),
dbc.Container(
id='container',
children=content,
fluid=True
),
# dummy component for callback triggering at startup
html.Div(id='dummy')
]
)
@app.callback(
[Output(f'{cid}', 'figure') for cid in component_ids],
Input('dummy', 'children')
)
def update(_):
# calling the plot functions
linux_category_bar_fig = student_category_bar_grade(students_category_earned, 'Linux')
windows_category_bar_fig = student_category_bar_grade(students_category_earned, 'Windows')
primer_category_bar_fig = student_category_bar_grade(students_category_earned, 'Primer')
linux_topic_scatter_polar_fig = student_topic_scatter_polar_graph(students_topics_earned,
'Linux')
windows_topic_scatter_polar_fig = student_topic_scatter_polar_graph(students_topics_earned,
'Windows')
primer_topic_scatter_polar_fig = student_topic_scatter_polar_graph(students_topics_earned,
'Primer')
return [
linux_topic_scatter_polar_fig,
windows_topic_scatter_polar_fig,
primer_topic_scatter_polar_fig,
linux_category_bar_fig,
windows_category_bar_fig,
primer_category_bar_fig
]
if __name__ == '__main__':
app.run_server(host="0.0.0.0", port=8070, debug=True)
which creates: