简体   繁体   English

如何从放大的 matplotlib.pyplot 图中读取新的限制?

[英]How can I read new limits from a zoomed matplotlib.pyplot figure?

I have 2 questions, marked Q1, Q2 below.我有 2 个问题,在下面标记为 Q1、Q2。 Q1 is the main one, Q2 is of secondary importance. Q1 是主要的,Q2 是次要的。 I want to read new limits from a zoomed matplotlib.pyplot figure.我想从放大的matplotlib.pyplot图中读取新的限制。 That is, I expect something like the following steps take place:也就是说,我希望发生以下步骤:

  1. There is a set of data, say y_i where i=0...9999有一组数据,比如 y_i 其中 i=0...9999
  2. Full set is drawn with a matplotlib.pyplot.plot command使用matplotlib.pyplot.plot命令绘制完整集
  3. User looks at the data and zooms into it with the built-in-the-figure-window magnifying-glass operation用户查看数据并使用内置图形窗口放大镜操作放大数据
  4. When user is happy with the zooming, he/she gives a message ( Q1: how?) to the program "I'm happy with these (horizontal) limits, read them and save them"当用户对缩放感到满意时,他/她会向程序发送一条消息( Q1:如何?)“我对这些(水平)限制感到满意,请阅读并保存它们”
  5. The code reads in the current horizontal values ( Q2: can the figure window remain open? If yes, then steps (6-7) apply)代码读取当前水平值( Q2:图形窗口可以保持打开状态吗?如果是,则步骤(6-7)适用)
  6. If the user wants to choose another interval, he/she clicks "reset picture" button and goes back to step (3)如果用户想选择另一个间隔,他/她点击“重置图片”按钮并返回到步骤(3)
  7. When the user is happy, he/she closes the figure当用户高兴时,他/她关闭图形

If Q2 is "no" then steps (6-7) are replaced by another loop where the figure is closed in (5) and re-drawn and start from (1).如果 Q2 为“否”,则步骤 (6-7) 将替换为另一个循环,其中图形在 (5) 中关闭并重新绘制并从 (1) 开始。 I would be ok with that, but prefer a "Q2=yes" version.我可以接受,但更喜欢“Q2=yes”版本。

Based on get the key value when calling matplolib pyplot waitforbuttonpress() I guess plt.waitforbuttonpress() is somehow involved, but I cannot decipher the advice in that link.基于在调用 matplolib pyplot waitforbuttonpress() 时获取键值,我猜plt.waitforbuttonpress()以某种方式参与,但我无法破译该链接中的建议。 I have never used the "event" stuff in python.我从来没有在 python 中使用过“事件”的东西。 I'm hoping the plot window already has some built-in event s in it, can I access them somehow?我希望绘图窗口中已经有一些内置event ,我可以以某种方式访问​​它们吗? Example code:示例代码:

import numpy as np
import matplotlib.pyplot as plt
N = 9999
dt = 0.1 / 180 * np.pi  # 0.1 degree steps
tt = np.arange(0, N*dt, dt)
yy = np.sin(tt) + 0.05 * np.random.random(tt.shape)  # include some noise
fig = plt.figure()
plt.plot(tt,yy)
plt.show()
# now the user zooms in... and questions Q1, Q2 apply.

Ok, I found a solution, although I feel this is quite non-aesthetic.好的,我找到了一个解决方案,虽然我觉得这很不美观。 I would very much welcome better solutions.我非常欢迎更好的解决方案。 This one works, for both question Q1 and Q2, but has 2 drawbacks: (1) it uses a global variable, which I've been told is bad programming(?), and (2) it gives a deprecation warning.这个对问题 Q1 和 Q2 都有效,但有两个缺点:(1) 它使用了一个全局变量,我被告知这是糟糕的编程 (?),以及 (2) 它给出了弃用警告。 Code modification is motivated from https://matplotlib.org/3.3.1/gallery/widgets/rectangle_selector.html (h/t @tmdavison)代码修改的动机来自https://matplotlib.org/3.3.1/gallery/widgets/rectangle_selector.html (h/t @tmdavison)

import numpy as np
import matplotlib.pyplot as plt

def press_key_in_figure(event):
    global xlimits
    print("You pressed %s" % event.key)
    if event.key == 'a':
        xlimits = ax.get_xlim()  # floats
        print("new x-limits: %.2f %.2f" % xlimits)
    if event.key == 'b':
        ylimits = ax.get_ylim()  # floats
        print("new y-limits: %.2f %.2f" % ylimits)

xlimits = (0, 0)
N = 9999
dt = 0.1 / 180 * np.pi  # 0.1 degree steps
tt = np.arange(0, N*dt, dt)
yy = np.sin(tt) + 0.05 * np.random.random(tt.shape)  # include some noise
fig, ax = plt.subplots()
ax.plot(tt,yy)

fig.canvas.mpl_connect('key_press_event', press_key_in_figure)
plt.show()
# now the user zooms in... and questions Q1, Q2 apply.
print("The new x-limits after the window was closed are", xlimits)

When I run it and zoom the picture, and press "a" or "b" it gives out:当我运行它并缩放图片,然后按“a”或“b”时,它会给出:

C:\python\lib\tkinter\__init__.py:1705: MatplotlibDeprecationWarning: Toggling axes navigation from the keyboard is deprecated since 3.3 and will be removed two minor releases later.
  return self.func(*args)
You pressed a
new x-limits: 3.62 6.48
You pressed b
new y-limits: -0.73 -0.23

I'm not sure what "Toggling axes navigation" means;我不确定“切换轴导航”是什么意思; I'm not toggling anything here?我没有在这里切换任何东西? Interestingly, my python --version is 3.7.2 so it seems not to be removed, contrary to what is claimed in the warning.有趣的是,我的python --version是 3.7.2,所以它似乎没有被删除,这与警告中声称的相反。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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