Align secondary percentage y axis with primary y axis in Plotly

Viewed 928

I'm using Plotly to create a graph with two lines on the primary y axis and a bar chart on the secondary y axis showing the proportion of line2/line1.

The code is working fine but it is creating too many reference lines (the lines for the 1000, 2000, 3000... of the left axis and 1%, 2%, 3%... of the right axis).

Is it possible to align them? For example, 1000 and 1% would share the same reference line, or any other way that it always aligns both left and right axis.

Here is the code and the graph generate:

    fig = make_subplots(specs=[[{'secondary_y': True}]])
    
    fig.add_trace(go.Scatter(x=data['date'], y=data['y1'],
                    mode='lines+markers',
                    name='Y1'), secondary_y=False)
    
    fig.add_trace(go.Scatter(x=data['date'], y=data['y2'],
                    mode='lines+markers',
                    name='Y2'), secondary_y=False)
    
    fig.add_trace(go.Bar(x=data['date'], y=data['pct'],
                    name='PCT', opacity=0.5), secondary_y=True)
    
    fig.update_layout(title=f'Graph', yaxis2=dict(tickformat='.2%'))

Graph

2 Answers

I was able to make it work by setting both axes range mode to zero and then changing the scale ratio so that 1k aligns with 1%, 2k aligns with 2% and so on

fig.update_yaxes(rangemode='tozero', scaleanchor='y', scaleratio=1, constraintoward='bottom', secondary_y=True)
fig.update_yaxes(rangemode='tozero', scaleanchor='y2', scaleratio=0.00001, constraintoward='bottom', secondary_y=False)
    

Updated graph

One way is to make sure that both y-axes have the same number of ticks, and have equal relative space between each tick. Here's an example with:

fig.update_layout(yaxis1_tickvals = [40, 70, 100], yaxis2_tickvals = [4, 4.5, 5])

Plot 1:

enter image description here

Without that addition, the code sample below would have produced the following plot:

Plot 2:

enter image description here

Complete code:

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

# Create figure with secondary y-axis
fig = make_subplots(specs=[[{"secondary_y": True}]])

# Add traces
fig.add_trace(
    go.Scatter(x=[1, 2, 3], y=[40, 50, 100], name="yaxis data"),
    secondary_y=False,
)

fig.add_trace(
    go.Scatter(x=[2, 3, 4], y=[4, 5, 4], name="yaxis2 data"),
    secondary_y=True,
)

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

# 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.update_layout(yaxis1_tickvals = [40, 70, 100], yaxis2_tickvals = [4, 4.5, 5])

fig.show()
Related