Я знаю, что в StackOverflow существует множество похожих тем, но ни один из ответов не решил мою конкретную проблему.
Прежде всего, я пытаюсь нанести на фигуру двумерные точки данных из разных классов с помощью команды разброса. Программа использует события matplotlib, такие как button_press_event и motion_notify_event, и я предполагаю, что сразу после событий должны использоваться команды plt.show (). Основная проблема заключается в том, что после выполнения некоторых задач с событиями (например, надписью) я хочу обновить весь рисунок, но plt.show () блокирует возможность продолжения программы. На самом деле plt.show () должен блокировать программу, пока пользователь программы не решит идти вперед. Есть ли решение для контроля этого атрибута блокировки?
Я пробовал plt.ion (), plt.ioff (), plt.show (block = False), plt.draw (), plt.pause (0.001), глобальные переменные с циклом while и т. Д., Но безуспешно. Единственный способ, которым программа работает как-то правильно, - это когда все цифры закрываются внутри button_press_event, когда выполняется так называемое прямое условие, но это не очень удобное решение, если все фигуры закрываются при каждом обновлении точек данных.
Вот проблеск кода:
def draw_original_figure(random_sample, random_sample_label, random_sample_image, X_train_chosen, y_train_chosen, images_train_chosen, classes, accuracy, embedding, model, h=0.05):
global points1, im1, s_im1, xybox, x1, y1, fig1, classes1, points_to_plot, y_train_chosen1, accuracy1, random_sample1, embedding1, y_train_chosen1, h1, random_sample_label1, result1
fig1 = plt.gcf()
.
.
.
original_figure_plot()
fig1.canvas.mpl_connect('motion_notify_event', hover)
fig1.canvas.mpl_connect('button_press_event', click)
plt.show()
def hover(event):
# if the mouse is over the scatter points
if points1.contains(event)[0]:
# find out the index within the array from the event
inds = points1.contains(event)[1]["ind"]
ind = inds[0]
# get the figure size
w,h = fig1.get_size_inches()*fig1.dpi
ws = (event.x > w/2.)*-1 + (event.x <= w/2.)
hs = (event.y > h/2.)*-1 + (event.y <= h/2.)
# if event occurs in the top or right quadrant of the figure,
# change the annotation box position relative to mouse.
ab1.xybox = (xybox[0]*ws, xybox[1]*hs)
# make annotation box visible
ab1.set_visible(True)
# place it at the position of the hovered scatter point
ab1.xy =(x1[ind], y1[ind])
# set the image corresponding to that point
im1.set_data(s_im1[ind,:,:])
else:
#if the mouse is not over a scatter point
ab1.set_visible(False)
fig1.canvas.draw_idle()
def click(event):
# if the mouse is over the scatter points
if points1.contains(event)[0]:
# find out the index within the array from the event
inds = points1.contains(event)[1]["ind"]
ind = inds[0]
# if one specific point is chosen
if ind == len(x1)-1:
plt.scatter(x1[ind], y1[ind], s=25, marker='x', c='#556B2F')
q = question(True, ind)
# do nothing
if q == "":
original_figure_plot()
# quit the program
elif q == "q":
exit()
# continue the program without updating labels
elif q == "n":
result1 = copy.deepcopy(y_train_chosen1)
plt.close("all")
# continue the program after labels are updated
else:
result1 = copy.deepcopy(y_train_chosen1)
result1 = np.append(result1, [int(q)], axis=0)
plt.close("all")
else:
# if anyone else point is chosen
plt.scatter(x1[ind], y1[ind], s=8, c='k')
q = question(False, ind)
# do nothing
if q == "":
original_figure_plot()
# quit the program
elif q == "q":
exit()
# update labels
else:
y_train_chosen1[ind] = int(q)
original_figure_plot()
fig1.canvas.draw_idle()
Возможно, лучше использовать, например, другие библиотеки, такие как plotly или dash, но правда ли, что вы не можете обновить рисунок, не закрывая его, если используете события matplotlib ?? Я могу предоставить все файлы проекта, но я думаю, что если есть решение, оно должно быть сделано внутри этих функций.