Search code examples
pythonplotlyvisualizationyaxis

How to align two y-axis on zero?


I have a plot where I use two Y-axises, one bar chart and one line chart. Now I want the y-axis of the line chart (yaxis2) to be aligned with the y axis of the barchart (yaxis). Where yaxis is zero, yaxis2 should also be zero. I only want the y axis ticklabels to change and not the data in the plot that is shown with the bar chart and line chart. So only the linelabels(ticklabels) should be changed, with where yaxis is 0, yaxis2 is 0. How to do this?

bar_trace = go.Bar(x=line_s['Year/Quarter'], y=line_s['CUR (€)'], name='CUR (€)')

line_trace1 = go.Scatter(x=line_s['Year/Quarter'], y=line_s['CUR PP'], name='CUR PP', yaxis='y2', 
                        mode='lines+markers', line=dict(color='orange'))

layout = go.Layout(title='test', 
                   yaxis=dict(title='CUR (€)'),
                   yaxis2=dict(title='CUR PP (%)', overlaying='y', side='right', tickmode="sync"),
                   legend=dict(x=1.06))

fig = go.Figure(data=[bar_trace, line_trace1], layout=layout)

fig.show()

enter image description here


Solution

  • There is no "simple" way of doing it. It would be more of a manual method. This is based a little on the solution provided here. Of the two y-axes, the larger one is the left y-axis. So, first identify the max and min for y1 and y2 and a co-efficient which is the multiplier to be multiplied to the right axis to make it the same as the left one.

    In the layout(), you need to add range and provide the min and max for the left-axis. For the right axis, provide the values as the left-axis, except divided by the co-efficient. This will make the right axis longer and align both the axes.

    Also, if you want to see the grid lines aligned, you can use dtick which tells you how far each of the ticks need to be. I have set this to 5 for both. So, the ticks will align instead of having different number of ticks....

    Hope this is what you are looking for...

    import plotly.graph_objects as go
    ## Get max and min for the two y-axes
    y1_min=line_s['CUR (€)'].min()
    y1_max=line_s['CUR (€)'].max()
    y2_min=line_s['CUR PP'].min()
    y2_max=line_s['CUR PP'].max()
    coeff = (y1_max-y1_min)/(y2_max-y2_min) ## This is the multiplier
    
    bar_trace = go.Bar(x=line_s['Year/Quarter'], y=line_s['CUR (€)'], name='CUR (€)')
    
    line_trace1 = go.Scatter(x=line_s['Year/Quarter'], y=line_s['CUR PP'], name='CUR PP', yaxis='y2', 
                            mode='lines+markers', line=dict(color='orange'))
    
    ## Added range and dtick for both y-axes
    layout = go.Layout(title='test', 
                       yaxis=dict(title='CUR (€)', range=[y1_min, y1_max], dtick=(y1_max - y1_min)/5),
                       yaxis2=dict(title='CUR PP (%)', overlaying='y', side='right', tickmode="auto", 
                                   range=[y1_min/coeff, y1_max/coeff], dtick=(y2_max - y2_min)/5),
                       legend=dict(x=1.06))
    
    fig = go.Figure(data=[bar_trace, line_trace1], layout=layout)
    fig.show()
    

    enter image description here