Matplotlib bug:数据显示在脊椎上方,带有twinx()

时间:2014-04-08 16:31:56

标签: python matplotlib

我试图绘制两个相差几个数量级的数据集。经过一些研究(实际上是一次谷歌搜索)我发现了twinx()函数。

但是,我在使用它时遇到了一些麻烦。我使用这个工具制作出版物级的数字,并且有些东西让我烦恼。

系统:Ubuntu上的matplotlib v1.3.1,python v2.7.4

请考虑以下代码:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.ticker import MaxNLocator
from matplotlib.ticker import AutoMinorLocator


time = np.arange(0, 365, 1)
y1 = np.random.rand(len(time)) * np.exp(-0.03 * time)
y2 = 0.001 * np.random.rand(len(time)) * np.exp(-0.02 * time)

for i in range(30):
    y2[-i] = 0

fig = plt.figure(figsize=(8,6), dpi=300)
fig.subplots_adjust(hspace=0.0, right=0.9, top=0.94, left=0.12, bottom=0.07)
ax1 = fig.add_subplot(111)
ax2 = ax1.twinx()

for tl in ax1.get_yticklabels():
    tl.set_color('r')
for tl in ax2.get_yticklabels():
    tl.set_color('b')

for ax in [ax1, ax2]:
    ax.yaxis.set_major_locator(MaxNLocator(
        nbins=5,
        steps=[1,2,3,4,5,10],
        integer=False,
        symmetric=False,
        prune=None))
    ax.yaxis.set_minor_locator(AutoMinorLocator(4))

ax2.plot(time, y1, 'b-')
ax1.plot(time, y2, 'r-')
ax1.set_ylabel(r"y value", labelpad=15)
ax1.set_xlabel(r"x value")
ax1.set_xlim(0,365)
ax1.set_xticks(range(0,370,30))
ax1.xaxis.set_minor_locator(AutoMinorLocator(3))

fig.savefig("Errorplot.png", dpi=60)

现在,在查看这个低分辨率输出时,我没有看到任何奇怪的东西: Error plot

但是,在放大高分辨率(例如dpi=300)版本时,我会看到以下内容: Zoomed section of the error plot

很明显,第二轴的线条是在第一轴的脊柱上绘制的。

如何缓解此问题?有没有办法重绘轴实例的刺?

我尝试了什么

  • 更改plot()来电
  • 的顺序
  • zorder kwarg设置为-1,-10。即使ax2 zorder小于ax1,我也有这种行为。
  • 结合上述内容:ax2.spines['bottom'].set_zorder(10)

2 个答案:

答案 0 :(得分:4)

这篇文章似乎没有得到很多观点,但我发现它很有帮助,并希望添加另一种方法来改变zorder关闭它将帮助其他人的机会。 post更符合我的想法,但重要的是改变zorder,@ Ffisegydd概述了这一点。另一种方法是使用以下方法:

fig, ax1 = plt.subplots()
ax2 = ax1.twinx()
ax1.set_zorder(ax2.get_zorder()+1) # put ax1 in front of ax2 
ax1.patch.set_visible(False) # hide the 'canvas' 

ax1.plot(data1[:,0], data1[:,0])  # plot whatever data you want
ax2.plot(data2[:,0], data2[:,0])  # plot commands can precede the set_zorder command

我意识到这并没有直接解决问题,但希望它可以帮助像我这样的人找到这篇文章,寻找解决密切相关问题的解决方案。

答案 1 :(得分:2)

您可以使用matplotlib中的zorder kwarg来更改对象的绘制顺序,请参阅示例代码here

下面我添加了两个示例(我已经删除了大部分代码以节省空间)。在一个示例中,我将zorder设置为更大的值,这意味着它将被绘制到最后(因此在顶部)。在另一个示例中,我将zorder设置为-1,这意味着它将首先绘制(因此在下面)。

ax2.plot(time, y1, 'b-', zorder=5)
ax1.plot(time, y2, 'r-', zorder=5)

Example plot

ax2.plot(time, y1, 'b-', zorder=-1)
ax1.plot(time, y2, 'r-', zorder=-1)

Example plot 2