Python matplotlib具有混合z顺序的两个y轴

Python matplotlib具有混合z顺序的两个y轴,python,matplotlib,Python,Matplotlib,我想在两个y轴上绘制数据,这样第二个y轴上的一些数据在第一个y轴图形后面,部分在上面。本质上,我希望使用“全局”zorder参数。可能吗 下面是一个简单的例子: import numpy as np import matplotlib.pyplot as plt # generate data x = np.linspace(0,30,30) y1 = np.random.random(30)+x y2 = np.random.random(30)+x*2 # create figure f

我想在两个y轴上绘制数据,这样第二个y轴上的一些数据在第一个y轴图形后面,部分在上面。本质上,我希望使用“全局”zorder参数。可能吗

下面是一个简单的例子:

import numpy as np
import matplotlib.pyplot as plt

# generate data
x = np.linspace(0,30,30)
y1 = np.random.random(30)+x
y2 = np.random.random(30)+x*2

# create figure
fig, ax = plt.subplots()

# y1 axis
ax.plot(x,y1,lw=5,c='#006000', zorder=2)
ax.set_ylim((0,30))
ax.set_xlim((0,30))

# y2 axis
ax2 = ax.twinx()  # instantiate a second axes that shares the same x-axis
ax2.fill_between([0, 30], [10, 10], color='pink', lw=0, zorder=1)
ax2.fill_between([0, 30], [60, 60], y2=[10, 10], color='gray', lw=0, zorder=1)
ax2.plot(x, y2,'o',ms=3,c='black', zorder=3)
ax2.set_ylim((0,60))
ax2.set_xlim((0,30))

# move y1 axis to the front
ax.set_zorder(ax2.get_zorder()+1)
ax.patch.set_visible(False)


我希望背景填充颜色在背景中,但黑色数据点应该在绿线的顶部。我试图通过为这些曲线定义zorder参数来实现这一点,但显然zorder仅在一个轴内定义,而不是跨多个轴定义。

这里有一个解决方案,可以满足您的需要,尽管它在实现中可能不太理想

import numpy as np
import matplotlib.pyplot as plt

# generate data
x = np.linspace(0,30,30)
y1 = np.random.random(30)+x
y2 = np.random.random(30)+x*2

# create figure
fig, ax1 = plt.subplots()
ax2 = ax1.twinx()
ax3 = ax2.twiny()
ax1.get_shared_x_axes().join(ax2, ax3)

# line
ax1.plot(x,y1,lw=5,c='#006000')
ax1.set_ylim((0,30))
ax1.set_xlim((0,30))

# points
ax2.plot(x, y2,'o',ms=3,c='black')
ax2.set_ylim((0,60))

# fills
ax3.set_xticklabels([])
ax3.get_xaxis().set_visible(False)
ax3.fill_between([0, 30], [10, 10], color='pink', lw=0)
ax3.fill_between([0, 30], [60, 60], y2=[10, 10], color='gray', lw=0)

# order
ax3.zorder = 1 # fills in back
ax1.zorder = 2 # then the line
ax2.zorder = 3 # then the points
ax1.patch.set_visible(False)

plt.show()

两个轴之间似乎存在明确的关系(在本例中,系数为2)。因此,我们可以在同一个轴上绘制所有的图形,并通过因子缩放必要的部分。(这需要matplotlib>=3.1)


我在想类似的事情。这是可行的,但我希望有另一种更优雅的方式。
import numpy as np
import matplotlib.pyplot as plt

# generate data
x = np.linspace(0,30,30)
y1 = np.random.random(30)+x
y2 = np.random.random(30)+x*2

# create figure
fig, ax = plt.subplots()

f = lambda x: 2*x
g = lambda x: x/2
ax2 = ax.secondary_yaxis('right', functions=(f,g))

ax.plot(x, y1,lw=5,c='#006000', zorder=2)
ax.plot(x, g(y2),'o',ms=3,c='black', zorder=3)
ax.set_ylim((0,30))
ax.set_xlim((0,30))


ax.fill_between([0, 30], [5, 5], color='pink', lw=0, zorder=1)
ax.fill_between([0, 30], [30, 30], y2=[5, 5], color='gray', lw=0, zorder=0)

plt.show()