I have this dataset-
group sub_group value date
0 Animal Cats 12 today
1 Animal Dogs 32 today
2 Animal Goats 38 today
3 Animal Fish 1 today
4 Plant Tree 48 today
5 Object Car 55 today
6 Object Garage 61 today
7 Object Instrument 57 today
8 Animal Cats 44 yesterday
9 Animal Dogs 12 yesterday
10 Animal Goats 18 yesterday
11 Animal Fish 9 yesterday
12 Plant Tree 8 yesterday
13 Object Car 12 yesterday
14 Object Garage 37 yesterday
15 Object Instrument 77 yesterday
I want to have two series in a barchart. I want to have one series for today and I want to have another series for yesterday. Within each series, I want the bars to be split up by their sub-groups. For example, there would be one bar called "Animal - today" and it would sum up to 83 and, within that bar, there would be cats, dogs, etc.
I want to make a chart that is very similar to chart shown under "Bar charts with Long Format Data" on the docs, except that I have two series.
This is what I tried-
fig = make_subplots(rows = 1, cols = 1)
fig.add_trace(go.Bar(
y = df[df['date'] == 'today']['amount'],
x = df[df['date'] == 'today']['group'],
color = df[df['date'] == 'today']['sub_group']
),
row = 1, col = 1
)
fig.add_trace(go.Bar(
y = df[df['date'] == 'yesterday']['amount'],
x = df[df['date'] == 'yesterday']['group'],
color = df[df['date'] == 'yesterday']['sub_group']
),
row = 1, col = 1
)
fig.show()
I added a bounty because I want to be able to add the chart as a trace in my subplot.
I think your code will draw the intended graph except for the color settings, but if you want to separate each stacked graph by color, you will need to do some tricks. There may be another way to do this, but create two express graphs by date and reuse that data. To create that x-axis, add a column with the code that makes the group column a category. the second group needs to be shifted on the x-axis, so I add +0.5 to the x-axis. Set the array ([0.25,1.25,2.25]
) and string to center the x-axis scale on the created graph. Finally, duplicate legend items are made unique.
# group id add
df['gr_id'] = df['group'].astype('category').cat.codes
import plotly.express as px
import plotly.graph_objects as go
fig_t = px.bar(df.query('date == "today"'), x="gr_id", y="amount", color='sub_group')
fig_y = px.bar(df.query('date == "yesterday"'), x="gr_id", y="amount", color='sub_group')
fig = go.Figure()
for t in fig_t.data:
fig.add_trace(go.Bar(t))
for i,y in enumerate(fig_y.data):
y['x'] = y['x'] + 0.5
fig.add_trace(go.Bar(y))
fig.update_layout(bargap=0.05, barmode='stack')
fig.update_xaxes(tickvals=[0.25,1.25,2.25], ticktext=['Animal','Plant','Pbject'])
names = set()
fig.for_each_trace(
lambda trace:
trace.update(showlegend=False)
if (trace.name in names) else names.add(trace.name))
fig.update_layout(legend_tracegroupgap=0)
fig.show()
EDIT: This is achieved by using the pre-loaded subplotting functionality built into express.
import plotly.express as px
px.bar(df, x='group', y='amount', color='sub_group', facet_col='date')