简体   繁体   中英

Matplotlib: Aligning two y-axis around zero

I have a plot with two y-axis on a shared x-axis, and I want to make them align at y=0 so that I can draw a horizontal line to highlight the zero tick. currently the two axis are not aligned and I have to draw two line which is terrible. How can I achieve this?

在此处输入图片说明

I have a plot with two y-axis on a shared x-axis, and I want to make them align at y=0 so that I can draw a horizontal line to highlight the zero tick. currently the two axis are not aligned and I have to draw two line which is terrible. How can I achieve this?

在此处输入图片说明

I have a plot with two y-axis on a shared x-axis, and I want to make them align at y=0 so that I can draw a horizontal line to highlight the zero tick. currently the two axis are not aligned and I have to draw two line which is terrible. How can I achieve this?

在此处输入图片说明

I have a plot with two y-axis on a shared x-axis, and I want to make them align at y=0 so that I can draw a horizontal line to highlight the zero tick. currently the two axis are not aligned and I have to draw two line which is terrible. How can I achieve this?

在此处输入图片说明

Here's another way, which I think is more versatile.

import numpy as np
%matplotlib inline
import matplotlib.pyplot as plt

def align_zeros(axes):

    ylims_current = {}   #  Current ylims
    ylims_mod     = {}   #  Modified ylims
    deltas        = {}   #  ymax - ymin for ylims_current
    ratios        = {}   #  ratio of the zero point within deltas

    for ax in axes:
        ylims_current[ax] = list(ax.get_ylim())
                        # Need to convert a tuple to a list to manipulate elements.
        deltas[ax]        = ylims_current[ax][1] - ylims_current[ax][0]
        ratios[ax]        = -ylims_current[ax][0]/deltas[ax]
    
    for ax in axes:      # Loop through all axes to ensure each ax fits in others.
        ylims_mod[ax]     = [np.nan,np.nan]   # Construct a blank list
        ylims_mod[ax][1]  = max(deltas[ax] * (1-np.array(list(ratios.values()))))
                        # Choose the max value among (delta for ax)*(1-ratios),
                        # and apply it to ymax for ax
        ylims_mod[ax][0]  = min(-deltas[ax] * np.array(list(ratios.values())))
                        # Do the same for ymin
        ax.set_ylim(tuple(ylims_mod[ax]))

x = np.array(range(1,11))
y1 = 5*x-10
y2 = -10*x+5

fig = plt.figure()
ax1 = fig.add_subplot(111)

ax1.plot(x,y1,'r',label='y1')
ax1.set_ylabel('y1')

ax2 = ax1.twinx()
ax2.plot(x,y2,'g',label='y2')
ax2.set_ylabel('y2')

align_zeros([ax1,ax2])

ax1.legend(loc='upper left')
ax2.legend(loc='upper right')

plt.show()

enter image description here

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM