Multiple boxplots in subplots with plotly

I am trying to create a multiple boxplot app with subplots from plotly that lets me know the evolution of a variable separated by different criteria.

My code looks like this:

from plotly.subplots import make_subplots
import plotly.graph_objects as go

trace0 = go.Box(
    y=df[(df.tipo == 'n')]['p'],
    x=df[(df.tipo == 'n')]['m'], 
    name='N'
)

trace1 = go.Box(
    y=df[(df.tipo == 's')]['p'],
    x=df[(df.tipo == 's')]['m'], 
    name='S'
)


fig = make_subplots(rows=1, cols=2)

fig.append_trace(trace0, row = 1, col = 1)
fig.append_trace(trace1, row = 1, col = 2)

fig.show()

The output of this looks like:

enter image description here

What I am trying to get is something that would look like this, but for each subplot:

enter image description here

I do have two dummy variables that allow me to separate it in subplots.

Thank you

Upvotes: 0

Views: 3008

Answers (1)

Rob Raymond
Rob Raymond

Reputation: 31146

  • you have implied what your data is, have simulated data from this
  • have use plotly express instead of graph objects
  • core solution is add all of the traces associated with a figure to the required sub-plots. With you case of having box plots for value N and S in topo column means two traces need to be added to each sub-plot
  • there are a few cleanup actions on layout and traces to make xaxis work as required and remove duplicates from legend
import pandas as pd
import numpy as np
import plotly.express as px
from plotly.subplots import make_subplots

df = pd.DataFrame({**{"month":np.tile(pd.date_range("1-jul-2020", freq="M", periods=12),20)[0:200],
                   "tipo":np.random.choice(["N","S"],200)},
                   **{f"var{v}":np.random.uniform(2,5,200) for v in range(8)}})

fig = make_subplots(
    rows=3, cols=3, subplot_titles=[c for c in df.columns if "var" in c]
)

for v in range(8):
    for t in px.box(df, x="month", y=f"var{v}", color="tipo").data:
        fig.add_trace(t, row=(v//3)+1, col=(v%3)+1)

# modifications needed to fix up display of sub-plots
fig.update_layout(
    boxmode="group", margin={"l": 0, "r": 0, "t": 20, "b": 0}
).update_traces(showlegend=False, selector=lambda t: "var0" not in t.hovertemplate)

enter image description here

Upvotes: 2

Related Questions