python - 等到用户单击 Matplotlib 图中的按钮以继续程序
问题描述
我正在开发一个交互式程序,该程序将点放在 Matplotlib 图形上。该程序允许用户使用鼠标将这些点从其原始位置移动。当用户对新的点位置满意时,程序继续。
因为我的程序项目很大并且涵盖的范围远不止这些,所以我将它分成了几个文件。他们是:
- 函数.py
import numpy as np
import settings
def update(val):
settings.ct_plt.set_xdata(settings.x)
settings.ct_plt.set_ydata(settings.y)
settings.f_img.canvas.draw_idle()
def reset(event):
settings.x = settings.x0.copy()
settings.y = settings.y0.copy()
settings.ct_plt.set_xdata(settings.x)
settings.ct_plt.set_ydata(settings.y)
settings.f_img.canvas.draw_idle()
def button_press_callback(event):
'whenever a mouse button is pressed'
if event.inaxes is None:
return
if event.button != 1:
return
settings.pind = get_ind_under_point(event)
def button_release_callback(event):
'whenever a mouse button is released'
if event.button != 1:
return
settings.pind = None
def get_ind_under_point(event):
'get the index of the vertex under point if within epsilon tolerance'
tinv = settings.ax_img.transData
xr = np.reshape(settings.x,(np.shape(settings.x)[0],1))
yr = np.reshape(settings.y,(np.shape(settings.y)[0],1))
xy_vals = np.append(xr,yr,1)
xyt = tinv.transform(xy_vals)
xt, yt = xyt[:, 0], xyt[:, 1]
d = np.hypot(xt - event.x, yt - event.y)
indseq, = np.nonzero(d == d.min())
ind = indseq[0]
if d[ind] >= settings.epsilon:
ind = None
return ind
def motion_notify_callback(event):
'on mouse movement'
if settings.pind is None:
return
if event.inaxes is None:
return
if event.button != 1:
return
settings.x[settings.pind] = event.xdata
settings.y[settings.pind] = event.ydata
settings.ct_plt.set_xdata(settings.x)
settings.ct_plt.set_ydata(settings.y)
settings.f_img.canvas.draw_idle()
def centhappy(event):
settings.happy_pos = True
- 设置.py
import numpy as np
from matplotlib import pyplot as plt
def init():
global happy_pos
global x, y
global x0, y0
global epsilon
global pind
global f_img, ax_img
global ct_plt
global img
img = np.array([])
# initial positions
x0 = np.arange(0.,300.,30.)
y0 = np.arange(0.,300.,30.)
x = x0.copy()
y = y0.copy()
f_img, ax_img = plt.subplots(1, 1)
ct_plt, = ax_img.plot(x,y,color='r',linestyle='none',marker='x',markersize=8)
pind = None #active point
epsilon = 5 #max pixel distance
happy_pos = False
- 主文件
import numpy as np
import matplotlib.image as mpim
import time
from matplotlib.widgets import Button
from matplotlib import pyplot as plt
import functions as fct
import settings
settings.init()
settings.img = mpim.imread('pattern.png')
settings.ax_img.imshow(settings.img)
axres = plt.axes([0.1, 0.1, 0.12, 0.02])
bres = Button(axres, 'Reset')
bres.on_clicked(fct.reset)
axres_b = plt.axes([0.1, 0.3, 0.12, 0.02])
bres_b = Button(axres_b, 'happy')
bres_b.on_clicked(fct.centhappy)
settings.f_img.canvas.mpl_connect('button_press_event', fct.button_press_callback)
settings.f_img.canvas.mpl_connect('button_release_event', fct.button_release_callback)
settings.f_img.canvas.mpl_connect('motion_notify_event', fct.motion_notify_callback)
while not settings.happy_pos:
time.sleep(5)
coord = np.column_stack((settings.x,settings.y))
np.savetxt('my_file.dat',coord)
我的问题来自程序的等待部分。它应该等待全局变量settings.happy_pos
变为true
. 这就是我使用这个time.sleep(5)
命令的原因。我也试过:
input("press enter if you are happy with your points")
但是,在任何情况下,图形都没有创建,程序也没有响应。(程序在没有这个等待/输入部分的情况下工作);你知道如何解决这个问题吗?我应该使用线程吗?
PS:我在这里给出了我在这个例子中用于我的问题的随机图像。
解决方案
推荐阅读
- swift - SKTextureAtlas EXC_BAD_ACCESS
- ruby-on-rails - Rails、gems、require、zsh 和错误消息!由于与“要求”相关的问题,我无法加载我的应用程序
- c++ - 如何将空格、逗号和换行符分隔的整数从文件中读取到 C++ 中的向量数组中?
- smtp - 从 Payara 5 Java Mail 使用 GMail SMTP 的问题
- ruby-on-rails - ActionController::RoutingError (未初始化常量 Users::Confirmations) 错误的原因
- html - 将旋转文本居中
- laravel - 安装 Laravel 后出现“laravel:找不到命令”
- powershell - 从PowerShell中的文本文件获取多维数组
- c - 用C语言获取并显示结构数据类型的输入
- python - Queryset 的值不会填充 Django 中的模板标签