I have the following DF:
import pandas as pd df = pd.DataFrame({ "a": ["a1", "a1", "a1", "a2", "a2", "a2", "a3", "a3", "a3"], "b": ["b1", "b2", "b3", "b1", "b2", "b3", "b1", "b2", "b3"], "c": [10, 20, 30, 40, 50, 60, 80, 90, 100], "d": [100, 200, 300, 400, 500, 600, 1000, 2000, 3000] }) df a b c d 0 a1 b1 10 100 1 a1 b2 20 200 2 a1 b3 30 300 3 a2 b1 40 400 4 a2 b2 50 500 5 a2 b3 60 600 6 a3 b1 80 1000 7 a3 b2 90 2000 8 a3 b3 100 3000
I want to create 3 figures for column a: a1, a2 and a3. In the x-axis, for each graph, I have the same b1, b2 and b3. I want to use a loop instead of the code below, which is repetitive because the x-axis is the same for all figures (b1, b2, b3) and the data names are the same (ccc and ddd):
from plotly import graph_objects as go df1=df.query("a=='a1'") fig1 = go.Figure(data=[ go.Bar(name = "ccc", x=df1.b, y=df1.c), go.Bar(name = "ddd", x=df1.b, y=df1.d) ]) fig1.update_layout(barmode='group', title="fig1 for a1") df2=df.query("a=='a2'") fig2 = go.Figure(data=[ go.Bar(name = "ccc", x=df2.b, y=df2.c), go.Bar(name = "ddd", x=df2.b, y=df2.d) ]) fig2.update_layout(barmode='group', title="fig2 for a2") df3=df.query("a=='a3'") fig3 = go.Figure(data=[ go.Bar(name = "ccc", x=df3.b, y=df3.c), go.Bar(name = "ddd", x=df3.b, y=df3.d) ]) fig3.update_layout(barmode='group', title="fig3 for a3")
How do I create that loop?
Advertisement
Answer
Approach
There are a number of ways you can do this. The real challenge is rather how to reference them later. Here’s how you do it:
- Slice your dataframe using
frames = df['a'].unique()
, - loop through your subsets using
for i, f in enumerate(frames):
, - build figures as normal using
fig=go.Figure()
- add each new figure to a dictionary using
figs['fig'+str(i)] = fig
Now you can reference and show, for example, figure 1
using:
figs['fig1'].show()
Plot
Complete code
import pandas as pd from plotly import graph_objects as go df = pd.DataFrame({ "a": ["a1", "a1", "a1", "a2", "a2", "a2", "a3", "a3", "a3"], "b": ["b1", "b2", "b3", "b1", "b2", "b3", "b1", "b2", "b3"], "c": [10, 20, 30, 40, 50, 60, 80, 90, 100], "d": [100, 200, 300, 400, 500, 600, 1000, 2000, 3000] }) frames = df['a'].unique() # use to slice dataframe figs = {} # container for figures for i, f in enumerate(frames, start = 1): di = df[df['a']==f] fig = go.Figure() fig.add_bar(name = "ccc", x=di.b, y=di.c) fig.add_bar(name = "ddd", x=di.b, y=di.d) fig.update_layout(barmode='group', title="fig" + str(i) + " for a" + str(i)) figs['fig'+str(i)] = fig figs['fig1'].show()