【问题标题】:Dynamic interaction between Rectangle Selector and a matplotlib figure矩形选择器和matplotlib图形之间的动态交互
【发布时间】:2019-05-26 11:52:15
【问题描述】:

我正在开发一个交互式程序,它显示图像并让用户通过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 我在这个例子中使用的随机图像来回答我的问题。

【问题讨论】:

    标签: python matplotlib interactive


    【解决方案1】:

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

    您的目标 (1) 问题的根本原因是该图在初始 show() 之后从未明确更新。

    所以解决这个问题的一种方法是在functions.py中的line_select_callback函数的末尾添加以下行:

    plt.gcf().canvas.draw()
    

    (当然 plt 也需要在这个模块中导入)

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

    【讨论】:

    • 非常感谢!不,这个问题以前没有解决过(就像另一个问题:stackoverflow.com/questions/56312631/…)。在与同事讨论我的工作项目时,我被告知要以面向对象的方式重新编写我的程序......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-10-26
    • 1970-01-01
    • 2017-09-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多