Интерактивный сюжет питона - PullRequest
2 голосов
/ 11 апреля 2019

Я пытаюсь создать интерактивный сюжет.Рисунок представляет собой массив разброса, который должен обновляться в соответствии с пользовательскими нажатиями.Каждое нажатие на элемент массива должно изменить его цвет на красный и наоборот.В настоящее время похоже, что толчки работают, но по какой-то причине разброс не обновляется после каждого нажатия.

Как мне решить эту проблему?

import

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

### globals ###
N = 5
NN = (N-1)/2
M = 5
MM = (M-1)/2
z = np.ones((N , M) , dtype=int)

### functions ###
# button_press_event #
# return indices of pressed transducer #
def onpick(event):
    ix = int(MM + np.round(event.xdata))
    iy = int(NN - np.round(event.ydata))
    z[iy , ix] = not(z[iy , ix])
    return True

# key_press_event #
# quits process if user pressed 'q' #
def keypick(event):
    if (event.data != 'q'):
        return False
    return True

### main ###
xs = np.linspace(-MM , MM , M , endpoint=True)
ys = np.linspace(-NN , NN , N , endpoint=True)
xx , yy = np.meshgrid(xs , ys)

fig = plt.figure()
ax = fig.add_subplot(111)
ax.set_title('click on array element to select/remove it')
ax.scatter(xx , yy , s=75 , color='c' , marker='o')
ax.set_xlim(-(MM+1) , MM+1)
ax.set_ylim(-(NN+1) , NN+1)

while(1):
    fig.canvas.mpl_connect('button_press_event', onpick)
    scat_c = np.argwhere(z == 1)
    scat_r = np.argwhere(z == 0)
    print(scat_r)
    ax.scatter(xx[scat_c , :] , yy[: , scat_c] , s=50 , color='c' , marker='o')
    ax.scatter(xx[: , scat_r] , yy[: , scat_r] , s=50 , color='r' , marker='o')
    plt.show()
    if (fig.canvas.mpl_connect('key_press_event', keypick)):
        quit()

1 Ответ

0 голосов
/ 17 апреля 2019
well, after a few tries I did it.
attaching the code:

### imports ###
import sys
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import Button
from mpl_toolkits.mplot3d import Axes3D


### general defines ###
# assuming N,M are odd
N  = 9
xs = np.linspace(1 , N , N , endpoint=True)
ys = np.linspace(1 , N , N , endpoint=True)
xx , yy = np.meshgrid(xs , ys)
data = np.concatenate((xx.reshape(N*N,1), yy.reshape(N*N,1)), axis=1)


### classes ###
class Index(object):
    def push_button(self, event):
        arr     = np.flip(dynamicArr,0)
        figi = plt.figure()
        axi = figi.add_subplot(1,1,1,projection='3d')
        axi.plot_surface(xx,yy,arr)
        figi.show()


### main ###
fig, ax = plt.subplots()
plt.subplots_adjust(bottom=0.2)
ax.set_title('click on array element to select/remove it')
coll = ax.scatter(data[:, 0] , data[:, 1], color=["blue"]*N*N, picker = 5, s=[150]*N*N)
coll._facecolors[:, :] = (190, 63, 63, 1)
coll._edgecolors[:, :] = (190, 63, 63, 1)
ax.axis([0, N+1, 0, N+1])

dynamicArr = np.ones((N,N) , dtype=int)

def on_pick(event):
    row = int(N-1 - int(event.ind/N))
    col = int(event.ind%N)
    if dynamicArr[row, col] == 0:
        dynamicArr[row, col] = 1
        coll._facecolors[event.ind, :] = (190, 63, 63, 1)
        coll._edgecolors[event.ind, :] = (190, 63, 63, 1)
    else:
        dynamicArr[row, col] = 0
        coll._facecolors[event.ind, :] = (100, 100, 100, 100)   #(63 , 190 , 190 , 1)
        coll._edgecolors[event.ind, :] = (100, 100, 100, 100)   #(63 , 190 , 190 , 1)
    fig.canvas.draw()


# adding callback button to figure
callback = Index()
axdraw   = plt.axes([0.395, 0.05, 0.25, 0.075])
bdraw    = Button(axdraw, 'push button')
bdraw.on_clicked(callback.push_button)

# enabling interactive GUI
fig.canvas.mpl_connect('pick_event', on_pick)
plt.show()
...