本文介绍了RectangleSelector在缩放时消失的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我运行 this 示例并在缩放或移动选择周围的绘图窗口消失,直到取消选择移动或缩放工具,然后再次单击绘图窗口.

When I run this example and create a rectangular selection if I zoom or move the plot window around the selection disappears until I deselect the move or zoom tool and click on the plot window again.

我正在IPython笔记本中使用%matplotlib tkinter .

I am using %matplotlib tkinter in an IPython notebook.

我尝试将窗口缩放时发生的限制更改挂钩并将矩形选择设置为可见:

I've attempted hooking into the limit changes that occur when the window is zoomed and setting the rectangular selection to visible:

def persist_rect(newlims):
    rs = toggle_selector.RS
    print(rs.visible)
    rs.set_visible(True)
    rs.update()

current_ax.callbacks.connect('xlim_changed', persist_rect)
current_ax.callbacks.connect('ylim_changed', persist_rect)

但这似乎无济于事.甚至似乎没有将 toggle_selector.RS.visible 设置为false.

But this doesn't seem to do anything. It doesn't even appear that toggle_selector.RS.visible is ever set to false.

我也一直在查看 来源RectangleSelector,但我没有看到任何有启发性的东西.

I've also been looking at the source for RectangleSelector, but I haven't seen anything enlightening there.

我还发现,当我使用 RectangleSelector.extents = new_extents 修改所选区域的范围时,我遇到了这个问题.修改 .extents 时(例如,使用滑块控件),所选区域消失,直到我再次单击该图为止.

I've also discovered that I have this issue when I modify the extent of the selected region using RectangleSelector.extents = new_extents. When .extents is modified, for example with a slider widget, the selected region disappears until I click on the plot again.

如果按照@ImportanceOfBeingErnest 的建议使用 useblit=False 初始化 RectangleSelector,所有这些问题都会消失,但是,正如他们所说,这不是一个非常高效的解决方案.

All of these problems problems go away if the RectangleSelector is initialized with useblit=False as @ImportanceOfBeingErnest suggests, but, as they say, it's not a very performant solution.

推荐答案

draw_events 添加回调:

def mycallback(event):
    if RS.active:
        RS.update()
plt.connect('draw_event', mycallback)

使 RectangleSelector 在缩放或平移后仍然存在,并且与 useblit = True 兼容.

makes the RectangleSelector persist after zooming or panning, and is compatible with useblit=True.

例如,使用文档中的代码作为基础:>

For example, using the code from the docs as a base:

from __future__ import print_function
from matplotlib.widgets import RectangleSelector
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.widgets as widgets
import threading
import datetime as DT

def line_select_callback(eclick, erelease):
    'eclick and erelease are the press and release events'
    x1, y1 = eclick.xdata, eclick.ydata
    x2, y2 = erelease.xdata, erelease.ydata
    print("(%3.2f, %3.2f) --> (%3.2f, %3.2f)" % (x1, y1, x2, y2))
    print(" The button you used were: %s %s" % (eclick.button, erelease.button))

def toggle_selector(event):
    print(' Key pressed: {}'.format(event.key))
    if event.key in ['D', 'd'] and RS.active:
        print(' RectangleSelector deactivated.')
        RS.set_active(False)
        RS.set_visible(False)
        RS.update()
    if event.key in ['A', 'a'] and not RS.active:
        print(' RectangleSelector activated.')
        RS.set_active(True)
        RS.set_visible(True)
        RS.update()

def mycallback(event):
    if RS.active:
        # print('mycallback')
        RS.update()

# def persist_rect(newlims):
#     print('persist_rect')
#     RS.set_visible(True)
#     RS.update()

fig, ax = plt.subplots()
# figtype = type(fig)
# figtype._draw = figtype.draw
# def mydraw(self, renderer):
#     print('figure.draw')
#     self._draw(renderer)
# figtype.draw = mydraw

N = 100000
x = np.linspace(0.0, 10.0, N)

RS = RectangleSelector(ax, line_select_callback,
                       drawtype='box', useblit=True,
                       button=[1, 3],  # don't use middle button
                       minspanx=5, minspany=5,
                       spancoords='pixels',
                       interactive=True)

plt.plot(x, +np.sin(.2*np.pi*x), lw=3.5, c='b', alpha=.7)
plt.plot(x, +np.cos(.2*np.pi*x), lw=3.5, c='r', alpha=.5)
plt.plot(x, -np.sin(.2*np.pi*x), lw=3.5, c='g', alpha=.3)

plt.connect('key_press_event', toggle_selector)
plt.connect('draw_event', mycallback)
# ax.callbacks.connect('xlim_changed', persist_rect)
# ax.callbacks.connect('ylim_changed', persist_rect)

plt.show()

为什么 mycallback 起作用但 persist_rect 不起作用?


Why does mycallback work but persist_rect doesn't?

如果你取消注释上面注释掉的语句,你会得到一些打印输出,看起来像这样:

If you uncomment the commented-out statements above, you'll get some printed output which will look something as this:

figure.draw
mycallback
figure.draw
mycallback
(4.09, -0.53) --> (8.15, 0.38)
 The button you used were: 1 1
persist_rect
persist_rect
figure.draw
mycallback
 Key pressed: q

请注意,在 figure.draw 之前调用 persist_rect ,而在之后调用 mycallback .figure.draw 不绘制 RectangleSelection,但它绘制用于背景的 Rectangle.因此, figure.draw 会掩盖 RectangleSelection .因此,persist_rect 会暂时显示 RectangleSelection,但它无法持久化.mycallback 起作用是因为它在 figure.draw 之后被调用.

Notice that persist_rect gets called before figure.draw, while mycallback is called afterwards. figure.draw does not draw the RectangleSelection, but it does draw the Rectangle used for the background. So figure.draw obscures RectangleSelection.Thus persist_rect momentarily displays RectangleSelection, but it fails to persist.mycallback works because it is called after figure.draw.

这篇关于RectangleSelector在缩放时消失的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-30 14:38