Skip to content
Advertisement

How do I loop over multiple figures in plotly?

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:

  1. Slice your dataframe using frames = df['a'].unique(),
  2. loop through your subsets using for i, f in enumerate(frames):,
  3. build figures as normal using fig=go.Figure()
  4. 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

enter image description here

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()
User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement