[英]Why cannot I apply zoom axes range to dual axis, like I can pan axes range, for interactive matplotlib plot?
The below code example is modified from the basis on Matplotlib: Finding out xlim and ylim after zoom下面的代码示例是在Matplotlib 的基础上修改的:Finding out xlim and ylim after zoom
Basically, in that example, I want to have a dual x axis;基本上,在那个例子中,我想要一个双 x 轴; and I want the second (doubled) x axis to behave as the original one.
我希望第二个(加倍的)x 轴表现得像原来的那样。 So, the link uses a callback to do that.
因此,该链接使用回调来执行此操作。 However:
然而:
Here is an animated gif (Matplotlib 3.1.1, Python 3.7.4 on MSYS2/MINGW64 on Windows 10):这是一个动画 gif (Matplotlib 3.1.1, Python 3.7.4 on MSYS2/MINGW64 on Windows 10):
I truly, truly don't understand this.我真的,真的不明白这一点。 How come, when I just pan/drag the plot,
ax.get_xlim()
gives the right numbers, and ax22.set_xlim()
applies them - but when I zoom the plot, ax.get_xlim()
gives the right numbers, but ax22.set_xlim()
does NOT apply them (or rather, applies them, but late - that is, applies the data from previous request in the current request)?????!!为什么,当我只是平移/拖动 plot 时,
ax.get_xlim()
给出了正确的数字,而ax22.set_xlim()
应用了它们 - 但是当我缩放plot 时, ax22.set_xlim()
ax.get_xlim()
给出了正确的数字,但是ax22.set_xlim()
不应用它们(或者更确切地说,应用它们,但迟到 - 即在当前请求中应用来自先前请求的数据)?????!! What is this sorcery?!这是什么法术?!
And how can I get the dual ax22
to be synchronized with the original ax
axis, regardless if I drag or zoom in interactive mode?以及如何让双
ax22
与原始ax
轴同步,无论我是否在交互模式下拖动或放大?
The code:编码:
#!/usr/bin/env python3
import matplotlib
print("matplotlib.__version__ {}".format(matplotlib.__version__))
import matplotlib.pyplot as plt
#
# Some toy data
x_seq = [x / 100.0 for x in range(1, 100)]
y_seq = [x**2 for x in x_seq]
#
# Scatter plot
fig, ax = plt.subplots(1, 1)
ax.plot(x_seq, y_seq)
# https://stackoverflow.com/questions/31803817/how-to-add-second-x-axis-at-the-bottom-of-the-first-one-in-matplotlib
ax22 = ax.twiny() # instantiate a second axes that shares the same y-axis
# Move twinned axis ticks and label from top to bottom
ax22.xaxis.set_ticks_position("bottom")
ax22.xaxis.set_label_position("bottom")
# Offset the twin axis below the host
ax22.spines["bottom"].set_position(("axes", -0.06))
ax22.set_xlim(*ax.get_xlim())
#
# Declare and register callbacks
def on_xlims_change(axes):
print("updated xlims: ", ax.get_xlim())
ax22.set_xlim(*ax.get_xlim())
ax.callbacks.connect('xlim_changed', on_xlims_change)
fig.canvas.mpl_connect('button_release_event', on_xlims_change)
#
# Show
plt.show()
Thanks to @ImportanceOfBeingErnest - I think I have an example now, that behaves the way I want - also for differing axes' ranges:感谢@ImportanceOfBeingErnest - 我想我现在有一个例子,它的行为符合我想要的方式 - 也适用于不同的轴范围:
Basically, without a callback, and with setting labels manually, all works as @ImportanceOfBeingErnest mentioned - except, when zooming, the old set of labels will remain (and so, when you zoom in, you might see 10 ticks on the original axis, but only 1 tick on the dual);基本上,没有回调,并且手动设置标签,所有工作都像@ImportanceOfBeingErnest 提到的那样工作 - 除了缩放时,旧的标签集将保留(因此,当您放大时,您可能会在原始轴上看到 10 个刻度,但对偶只有 1 个刻度); so here, the callback is just used to "follow" the original axis labels:
所以在这里,回调仅用于“跟随”原始轴标签:
#!/usr/bin/env python3
import matplotlib
print("matplotlib.__version__ {}".format(matplotlib.__version__))
import matplotlib.pyplot as plt
#
# Some toy data
x_seq = [x / 100.0 for x in range(1, 100)]
y_seq = [x**2 for x in x_seq]
#
# Scatter plot
fig, ax = plt.subplots(1, 1)
ax.plot(x_seq, y_seq)
# https://stackoverflow.com/questions/31803817/how-to-add-second-x-axis-at-the-bottom-of-the-first-one-in-matplotlib
ax22 = ax.twiny() # instantiate a second axes that shares the same y-axis
# Move twinned axis ticks and label from top to bottom
ax22.xaxis.set_ticks_position("bottom")
ax22.xaxis.set_label_position("bottom")
# Offset the twin axis below the host
ax22.spines["bottom"].set_position(("axes", -0.06))
factor = 655
old_xlims = ax.get_xlim()
new_xlims = (factor*old_xlims[0], factor*old_xlims[1])
old_tlocs = ax.get_xticks()
new_tlocs = [i*factor for i in old_tlocs]
print("old_xlims {} new_xlims {} old_tlocs {} new_tlocs {}".format(old_xlims, new_xlims, old_tlocs, new_tlocs))
ax22.set_xticks(new_tlocs)
ax22.set_xlim(*new_xlims)
def on_xlims_change(axes):
old_tlocs = ax.get_xticks()
new_tlocs = [i*factor for i in old_tlocs]
ax22.set_xticks(new_tlocs)
ax.callbacks.connect('xlim_changed', on_xlims_change)
#
# Show
plt.show()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.