RectangleSelector 在缩放时消失
RectangleSelector Disappears on Zoom
当我 运行 this 示例并创建一个矩形选区时,如果我缩放或移动绘图 window 选区周围的选区会消失,直到我取消选择移动或缩放工具并单击情节再次 window。
我正在 IPython 笔记本中使用 %matplotlib tkinter
。
我试图了解 window 缩放时发生的限制变化并将矩形选区设置为可见:
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。
我也一直在看 source for RectangleSelector,但我没有看到任何有启发性的东西。
我还发现,当我使用 RectangleSelector.extents = new_extents
修改所选区域的范围时,我也遇到了这个问题。当 .extents
被修改时,例如使用滑块小部件,所选区域会消失,直到我再次单击绘图。
如果按照@ImportanceOfBeingErnest 的建议用 useblit=False
初始化 RectangleSelector
,所有这些问题都会消失,但是,正如他们所说,这不是一个非常高效的解决方案。
如果我没理解错的话,矩形选择器应该在整个平移或缩放过程中保持可见。这可以通过不使用 blitting 来实现,
toggle_selector.RS = RectangleSelector(ax, ..., useblit=False, ...)
这样做的一个副作用是绘图可能会变慢,具体取决于绘图的复杂程度,因为如果不使用 blitting,则在使用矩形选择器时会不断重绘整个绘图。
在 RectangularSelector the release method (line 2119 的源代码中)
处理选择器的可见性
def _release(self, event):
"""on button release event"""
if not self.interactive:
self.to_draw.set_visible(False)
子类RectangleSelector修改release方法
class visibleRectangleSelector(RectangleSelector):
def release(self, event):
super(visibleRectangleSelector, self).release(event)
self.to_draw.set_visible(True)
self.canvas.draw() ##updates canvas for new selection
示例代码使用 doc 示例
from __future__ import print_function
"""
Do a mouseclick somewhere, move the mouse to some destination, release
the button. This class gives click- and release-events and also draws
a line or a box from the click-point to the actual mouseposition
(within the same axes) until the button is released. Within the
method 'self.ignore()' it is checked whether the button from eventpress
and eventrelease are the same.
"""
from matplotlib.widgets import RectangleSelector
import numpy as np
import matplotlib.pyplot as plt
class visibleRectangleSelector(RectangleSelector):
def release(self, event):
super(visibleRectangleSelector, self).release(event)
self.to_draw.set_visible(True)
self.canvas.draw()
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.')
if event.key in ['Q', 'q'] and toggle_selector.RS.active:
print(' RectangleSelector deactivated.')
toggle_selector.RS.set_active(False)
if event.key in ['A', 'a'] and not toggle_selector.RS.active:
print(' RectangleSelector activated.')
toggle_selector.RS.set_active(True)
fig, current_ax = plt.subplots() # make a new plotting range
N = 100000 # If N is large one can see
x = np.linspace(0.0, 10.0, N) # improvement by use blitting!
plt.plot(x, +np.sin(.2 * np.pi * x), lw=3.5, c='b', alpha=.7) # plot something
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)
print("\n click --> release")
# drawtype is 'box' or 'line' or 'none'
toggle_selector.RS = RectangleSelector(
current_ax,
line_select_callback,
drawtype='box',
useblit=False,
button=[1, 3], # don't use middle button
minspanx=5,
minspany=5,
spancoords='pixels',
interactive=True)
plt.connect('key_press_event', toggle_selector)
plt.show()
为 draw_event
秒添加回调:
def mycallback(event):
if RS.active:
RS.update()
plt.connect('draw_event', mycallback)
使 RectangleSelector
在缩放或平移后保持不变,并与 useblit=True
兼容。
例如,使用code from the docs作为基础:
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
无效?
如果您取消对上面注释掉的语句的注释,您将得到一些如下所示的打印输出:
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
请注意 persist_rect
在 figure.draw
之前被调用,而 mycallback
在之后被调用。 figure.draw
不绘制 RectangleSelection
,但绘制用于背景的 Rectangle
。所以 figure.draw
掩盖了 RectangleSelection
。
因此 persist_rect
暂时显示 RectangleSelection
,但无法持续。
mycallback
有效,因为它是在 figure.draw
.
之后调用的
当我 运行 this 示例并创建一个矩形选区时,如果我缩放或移动绘图 window 选区周围的选区会消失,直到我取消选择移动或缩放工具并单击情节再次 window。
我正在 IPython 笔记本中使用 %matplotlib tkinter
。
我试图了解 window 缩放时发生的限制变化并将矩形选区设置为可见:
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。
我也一直在看 source for RectangleSelector,但我没有看到任何有启发性的东西。
我还发现,当我使用 RectangleSelector.extents = new_extents
修改所选区域的范围时,我也遇到了这个问题。当 .extents
被修改时,例如使用滑块小部件,所选区域会消失,直到我再次单击绘图。
如果按照@ImportanceOfBeingErnest 的建议用 useblit=False
初始化 RectangleSelector
,所有这些问题都会消失,但是,正如他们所说,这不是一个非常高效的解决方案。
如果我没理解错的话,矩形选择器应该在整个平移或缩放过程中保持可见。这可以通过不使用 blitting 来实现,
toggle_selector.RS = RectangleSelector(ax, ..., useblit=False, ...)
这样做的一个副作用是绘图可能会变慢,具体取决于绘图的复杂程度,因为如果不使用 blitting,则在使用矩形选择器时会不断重绘整个绘图。
在 RectangularSelector the release method (line 2119 的源代码中) 处理选择器的可见性
def _release(self, event):
"""on button release event"""
if not self.interactive:
self.to_draw.set_visible(False)
子类RectangleSelector修改release方法
class visibleRectangleSelector(RectangleSelector):
def release(self, event):
super(visibleRectangleSelector, self).release(event)
self.to_draw.set_visible(True)
self.canvas.draw() ##updates canvas for new selection
示例代码使用 doc 示例
from __future__ import print_function
"""
Do a mouseclick somewhere, move the mouse to some destination, release
the button. This class gives click- and release-events and also draws
a line or a box from the click-point to the actual mouseposition
(within the same axes) until the button is released. Within the
method 'self.ignore()' it is checked whether the button from eventpress
and eventrelease are the same.
"""
from matplotlib.widgets import RectangleSelector
import numpy as np
import matplotlib.pyplot as plt
class visibleRectangleSelector(RectangleSelector):
def release(self, event):
super(visibleRectangleSelector, self).release(event)
self.to_draw.set_visible(True)
self.canvas.draw()
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.')
if event.key in ['Q', 'q'] and toggle_selector.RS.active:
print(' RectangleSelector deactivated.')
toggle_selector.RS.set_active(False)
if event.key in ['A', 'a'] and not toggle_selector.RS.active:
print(' RectangleSelector activated.')
toggle_selector.RS.set_active(True)
fig, current_ax = plt.subplots() # make a new plotting range
N = 100000 # If N is large one can see
x = np.linspace(0.0, 10.0, N) # improvement by use blitting!
plt.plot(x, +np.sin(.2 * np.pi * x), lw=3.5, c='b', alpha=.7) # plot something
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)
print("\n click --> release")
# drawtype is 'box' or 'line' or 'none'
toggle_selector.RS = RectangleSelector(
current_ax,
line_select_callback,
drawtype='box',
useblit=False,
button=[1, 3], # don't use middle button
minspanx=5,
minspany=5,
spancoords='pixels',
interactive=True)
plt.connect('key_press_event', toggle_selector)
plt.show()
为 draw_event
秒添加回调:
def mycallback(event):
if RS.active:
RS.update()
plt.connect('draw_event', mycallback)
使 RectangleSelector
在缩放或平移后保持不变,并与 useblit=True
兼容。
例如,使用code from the docs作为基础:
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
无效?
如果您取消对上面注释掉的语句的注释,您将得到一些如下所示的打印输出:
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
请注意 persist_rect
在 figure.draw
之前被调用,而 mycallback
在之后被调用。 figure.draw
不绘制 RectangleSelection
,但绘制用于背景的 Rectangle
。所以 figure.draw
掩盖了 RectangleSelection
。
因此 persist_rect
暂时显示 RectangleSelection
,但无法持续。
mycallback
有效,因为它是在 figure.draw
.