矩形选择器和matplotlib图形之间的动态交互

时间:2019-05-26 11:52:15

标签: python matplotlib interactive

我正在开发一个交互式程序,该程序显示图像并允许用户通过RectangleSelector选择该图像的一部分。目标是该程序

  1. 首先,实时显示图像所选部分中三个运河的最小值
  2. 在用户满意时保存矩形的坐标,以便程序继续执行

由于我的程序项目很大,而且涵盖的范围远远超过此,因此我将其拆分为几个文件。这是他们:

  • settings.py
import numpy as np

def init():

    global img # image
    global text_sig_red, text_sig_green, text_sig_blue

#    text_sig_red, text_sig_green, text_sig_blue = '', '', ''

    img = np.array([])
  • functions.py
import numpy as np
import settings

def line_select_callback(eclick, erelease):

#    'eclick and erelease are the press and release events'
    x1, y1 = int(eclick.xdata), int(eclick.ydata) # start position
    x2, y2 = int(erelease.xdata), int(erelease.ydata) # end position

    crop_img = settings.img[x1:x2,y1:y2]
    #print('shape film temoin', np.shape(film_temoin))

    sig_red = np.min(crop_img[:,:,0])
    sig_green = np.min(crop_img[:,:,1])
    sig_blue = np.min(crop_img[:,:,2])

    text_red = 'min red signal' + str(sig_red)
    text_green = 'min green signal' + str(sig_green)
    text_blue = 'min blue signal' + str(sig_blue)

    settings.text_sig_red.set_text(text_red)
    settings.text_sig_green.set_text(text_green)
    settings.text_sig_blue.set_text(text_blue)

def toggle_selector(event):
    if event.key in ['Q', 'q'] and toggle_selector.RS.active:
        toggle_selector.RS.set_active(False)
    if event.key in ['A', 'a'] and not toggle_selector.RS.active:
        toggle_selector.RS.set_active(True)
  • main.py
import numpy as np
import matplotlib.image as mpim
import matplotlib.animation as animation
import matplotlib.patches as patches
from matplotlib.widgets import RectangleSelector
from matplotlib import pyplot as plt

import functions as fct
import settings

settings.init()

settings.img = mpim.imread('pattern.png')

fig, ax = plt.subplots(1, 1)

ax_red = plt.axes([0.05, 0.5, 0.05, 0.02])
ax_green = plt.axes([0.05, 0.3, 0.05, 0.02])
ax_blue = plt.axes([0.05, 0.1, 0.05, 0.02])

settings.text_sig_red = ax_red.text(0.5,0.5,"",transform=ax_red.transAxes)
settings.text_sig_green = ax_green.text(0.5,0.5,"",transform=ax_green.transAxes)
settings.text_sig_blue = ax_blue.text(0.5,0.5,"",transform=ax_blue.transAxes)

ax.imshow(settings.img)

fct.toggle_selector.RS = RectangleSelector(ax, fct.line_select_callback,
                                           drawtype='box', useblit=True,
                                           button=[1, 3],  # don't use middle button
                                           minspanx=5, minspany=5,
                                           spancoords='pixels',
                                           interactive=True,
                                           rectprops=dict(facecolor='black', 
                                                          edgecolor = 'black',
                                                          alpha=1.,
                                                          fill=None))

plt.connect('key_press_event', fct.toggle_selector)

plt.show()

当前,我在程序目标(1)方面遇到麻烦。它不会动态显示文本text_sig_red

实际上,当用户满意时,我不知道如何保存矩形的坐标。也许用户应该停止触摸矩形的位置和范围,然后单击按钮以使程序继续运行(这是我遇到的另一个问题linked

PS:我给了here这个示例中用于解答问题的随机图像。

1 个答案:

答案 0 :(得分:1)

希望您的问题现在已经解决,但如果没有解决

目标(1)出现问题的根本原因是,在初始show()之后,该图永远不会显式更新。

因此,解决此问题的一种方法是将以下行添加到functions.py中的line_select_callback函数的末尾:

plt.gcf().canvas.draw()

(当然,还需要在此模块中导入plt)

关于其余的问题,创建明显的交互(例如按钮)始终是一个不错的选择。