Search code examples
pythonplotlyboxplotyaxis

Secondary y axis using boxplots with plotly


I want to implement a secondary y-axis in a subplot using plotly. Most of the code is copied from here.

The error is: 'Invalid property specified for object of type plotly.graph_objs.Box: 'secondary'. Is it because I cannot use the 'go.Box' in this case?

Here is the code:

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

x = ['day 1', 'day 1','day 1',
    'day 2', 'day 2', 'day 2']
fig = make_subplots(specs=[[{"secondary_y": True}]])

# Add traces
fig.add_trace(go.Box(  
y=[56.3 , 56.3 , 56.3 , 51.  , 49. ],
x=x,
name='Test1',
marker_color='#3D9970',
secondary_y=False,
))

fig.add_trace(go.Box(
y=[1 , 2 , 3 , 2  , 1 ],
x=x,
name='Test2',
marker_color='#3D9970',
secondary_y=True,
))

# Add figure title
fig.update_layout(
title_text="Double Y Axis Example",
boxmode='group'
)

# Set x-axis title
fig.update_xaxes(title_text="xaxis title")

# Set y-axes titles
fig.update_yaxes(title_text="<b>primary</b> yaxis title", secondary_y=False)
fig.update_yaxes(title_text="<b>secondary</b> yaxis title", secondary_y=True)

fig.show()

Solution

  • Secondary_y is a property of fig.add_trace() and not go.Box(). That does not mean you can't use go.Box() on a secondary y-axis. On the contrary. Just move secondary_y outside the parentheses of go.Box in your setup, and you'll get this:

    Plot:

    enter image description here

    Complete code:

    import plotly.graph_objects as go
    from plotly.subplots import make_subplots
    
    x = ['day 1', 'day 1','day 1',
        'day 2', 'day 2', 'day 2']
    fig = make_subplots(specs=[[{"secondary_y": True}]])
    
    # Add traces
    fig.add_trace(go.Box(  
    y=[56.3 , 56.3 , 56.3 , 51.  , 49. ],
    x=x,
    name='Test1',
    marker_color='#3D9970',
    
    ),secondary_y=False,)
    
    fig.add_trace(go.Box(
    y=[1 , 2 , 3 , 2  , 1 ],
    x=x,
    name='Test2',
    marker_color='#3D9970',
    
    ),secondary_y=True,)
    
    # Add figure title
    fig.update_layout(
    title_text="Double Y Axis Example",
    boxmode='group'
    )
    
    # Set x-axis title
    fig.update_xaxes(title_text="xaxis title")
    
    # Set y-axes titles
    fig.update_yaxes(title_text="<b>primary</b> yaxis title", secondary_y=False)
    fig.update_yaxes(title_text="<b>secondary</b> yaxis title", secondary_y=True)
    
    fig.show()