Matplotlib在附加轴上的错误位置打勾

时间:2014-02-24 02:47:14

标签: python matplotlib customization

我希望上方的X轴在相同位置(在轴上)具有刻度,因为原始x轴刻度(尽管刻度标签可以不同)。这似乎很容易,但我不确定为什么下面的代码不起作用:

import numpy as np
import matplotlib.pyplot as plt

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

X = np.linspace(11,80,1000)
Y = 2*np.sin(X)*np.exp(-X/20.)

ax1.plot(X,Y)
ax2 = ax1.twiny()

old_ticks = ax1.get_xticks()
ax2.set_xticks(old_ticks)

plt.show()

输出显示如下:显然,顶轴上的刻度不在轴上与下面的刻度相同的位置(即,在顶部轴上有7个刻度,而底部只有6个刻度)。

为什么会这样?

Offset ticks on the second x axis

编辑:设置xlim(如下所示)仅适用于初始绘图,但不适用于放大不同区域的情况。我添加了一个回调函数,在放大/缩小时,将ax2上的刻度添加到与ax1相同的位置,但这似乎不起作用。

另外,我使用twiny的原因是因为ax2最终显示的刻度值将以非线性方式取决于ax1刻度值。我只想让刻度线位于轴上的相同位置。     导入numpy为np     将matplotlib.pyplot导入为plt

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

X = np.linspace(11,80,1000)
Y = 2*np.sin(X)*np.exp(-X/20.)

ax1.plot(X,Y)
ax2 = ax1.twiny()

ax2.set_xlim(ax1.get_xlim())
ax2.set_xticks(ax1.get_xticks())

def on_xlim_changed(ax1):
    ax2.set_xlim(ax1.get_xlim())
    ax2.set_xticks(ax1.get_xticks())

ax1.callbacks.connect('xlim_changed',on_xlim_changed)

plt.show()

3 个答案:

答案 0 :(得分:2)

尝试:

ax2.set_xlim(ax1.get_xlim())

另外,如果您只需要在顶部显示刻度线,则不需要twiny轴,您可以直接执行

ax1.xaxis.set_ticks_position('both')

答案 1 :(得分:1)

此处的技巧是使用ax2.set_navigate(False)禁用辅助轴上的缩放。仅当缩放不影响轴本身的限制时,才在回调中调整限制才有效:

import numpy as np
import matplotlib.pyplot as plt

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

x = np.linspace(11, 80, 1000)
y = 2 * np.sin(x) * np.exp(-x / 20.)

ax1.plot(x, y)
ax2 = ax1.twiny()
ax2.set_navigate(False)  # Important!

old_ticks = ax1.get_xticks()
ax2.set_xticks(old_ticks)
ax1.grid(linewidth=1, ls='--') # Added to be able to see the (mis-)alignment better.

ax2.set_xlim(ax1.get_xlim())

def on_xlim_changed(ax_):
    ax2.set_xticks(ax_.get_xticks())
    ax2.set_xlim(ax_.get_xlim())

ax1.callbacks.connect('xlim_changed', on_xlim_changed)

plt.show()

不使用set_navigate(False)进行缩放的示例

Zooming w/o <code>set_navigate(False)</code>

放大答案中发布的代码

Zooming with the code as posted in the answer

答案 2 :(得分:0)

您应该使用Locator功能

import matplotlib.ticker as mticks

N = 5
ax1.get_xaxis().set_major_locator(mticks.LinearLocator(numticks=N))
ax2.get_xaxis().set_major_locator(mticks.LinearLocator(numticks=hN))

doc)会在轴上放置N均匀间隔的刻度线。

然后Formatter将负责格式化标签。

请注意,这可以倾向于非常奇怪的标签。位置跳跃的原因是AutoLocator,它是默认定位器,试图将刻度线放在“好”位置(整数,甚至是倍数等),因此您不会得到看起来像'的刻度标签1.52547841082' 。