Search code examples
pythonplotlyboxplotsubplot

iteratively plot boxplots (subplots) with pre-computed data


I am trying to iteratively plot different boxplots (subplots) with pre-computed quantiles. the data looks somehow like this

df = pd.DataFrame({"feature":['a', 'a', 'b', 'b', 'c', 'c'],
                        "date":['2022-01-01', '2022-01-02', '2022-01-01', '2022-01-02', '2022-01-01', '2022-01-02'],
                        "min": [0,0,9000,8000,30,35],
                        "q25": [12,15,21000,15000,40,45],
                        "q50": [90,100,21000,15000,50,55],
                        "q75": [1500,1300,50000,60000,60,65],
                        "max": [4000, 3500, 150000,200000,70,75]})

what I would like to see in this case are three charts each with two boxplots: one chart for each feature. And each chart with 2 boxplots - one for each date. And with the feature name as title over each chart

And what I am getting with the following code is 6 boxplots in one chart:

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

for i in (pd.value_counts(df['feature'])):
    fig.add_trace(go.Box(lowerfence = df["min"], q1 = df["q25"]
    , median = df["q50"], q3 = df["q75"], upperfence = df["max"]))

any help is very much appreciated!


Solution

  • To subplot by function name, first specify a subplot based on the data extracted by function name. To set a function name title for each, add it to the initial subplot settings. I also set the vertical spacing and x-axis sharing.

    import plotly.graph_objects as go
    from plotly.subplots import make_subplots
    
    fig = make_subplots(rows=3, cols=1,
                        shared_xaxes=True,
                        vertical_spacing=0.1,
                       subplot_titles=df['feature'].unique())
    
    for i,f in enumerate(df['feature'].unique()):
        dff = df.query('feature == @f')
        fig.add_trace(go.Box(
            name=f,
            x=dff['date'],
            lowerfence = dff["min"],
            q1 = dff["q25"],
            median = dff["q50"],
            q3 = dff["q75"],
            upperfence = dff["max"]
        ), row=i+1, col=1)
    
    fig.update_layout(height=600, width=600)
    fig.show()
    

    enter image description here