user140259
user140259

Reputation: 480

Plot plotly boxplots in subplots using for loop

I have a Dataframe (df). I want to plot boxplot of each of the columns, and that these are displayed as subplots. However, the following code gives an error.

from plotly.subplots import make_subplots
import plotly.express as px
import pandas as pd

fig = make_subplots(rows = 5, cols = 2)
for i, column in enumerate(df.select_dtypes(include = np.number).columns.tolist()):
    fig.add_trace(px.box(df, y = [column]), row = i%5, col = i//5)
    fig.update_layout(width = 800, height = 800)
    fig.show()

Error: "----> 5 fig.add_trace(px.box(df, y = [column]), row = i%5, col =i//5)"

Upvotes: 2

Views: 2467

Answers (1)

vestland
vestland

Reputation: 61084

On my end your code snippet triggers:

The 'data' property is a tuple of trace instances that may be specified as:

  • A list or tuple of trace instances (e.g. [Scatter(...), Bar(...)])
  • A single trace instance

This is because fig.add_trace is designed to take trace objects as inputs, such as go.Box, and not figure objects which is what will be returned by px.box that you are using here. So instead of that, you can use something like:

# plotly setup
plot_rows=6
plot_cols=6
fig = make_subplots(rows=plot_rows, cols=plot_cols)

# add traces
x = 0
for i in range(1, plot_rows + 1):
    for j in range(1, plot_cols + 1):
        #print(str(i)+ ', ' + str(j))
        fig.add_trace(go.Box(y=df[df.columns[x]].values,
                                 name = df.columns[x],
                            ),
                     row=i,
                     col=j)

        x=x+1

And get:

enter image description here

Complete code:

## imports
from plotly.subplots import make_subplots
import plotly.graph_objs as go
import pandas as pd
import numpy as np

# data
np.random.seed(123)
frame_rows = 10
n_plots = 36
frame_columns = ['B_'+str(e) for e in list(range(n_plots+1))]
df = pd.DataFrame(np.random.uniform(-10,10,size=(frame_rows, len(frame_columns))),
                  index=pd.date_range('1/1/2020', periods=frame_rows),
                    columns=frame_columns)
df=df.cumsum()+100
df.iloc[0]=100

# plotly setup
plot_rows=6
plot_cols=6
fig = make_subplots(rows=plot_rows, cols=plot_cols)

# add traces
x = 0
for i in range(1, plot_rows + 1):
    for j in range(1, plot_cols + 1):
        #print(str(i)+ ', ' + str(j))
        fig.add_trace(go.Box(y=df[df.columns[x]].values,
                                 name = df.columns[x],
                            ),
                     row=i,
                     col=j)

        x=x+1

# Format and show fig
fig.update_layout(height=1200, width=1200)
fig.show()

Upvotes: 3

Related Questions