日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > python >内容正文

python

python3环境下用matplotlib库实现UI交互

發(fā)布時間:2024/9/30 python 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python3环境下用matplotlib库实现UI交互 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

在python的學(xué)習(xí)過程中我看到一個模擬鳥群的例子,并可以用鼠標(biāo)左鍵創(chuàng)建一只新的鳥,用鼠標(biāo)右鍵驅(qū)散鳥群。在我運(yùn)行代碼的時候發(fā)現(xiàn),點(diǎn)擊鼠標(biāo)左鍵和右鍵均沒有反應(yīng)。于是查閱資料,最后找到了問題所在,現(xiàn)在將解決問題的過程記錄下來,(如果只要結(jié)果的同學(xué)直接拉到最底下就可以了)

測試環(huán)境:
Win10,python3.6.4,matplotlib 2.1.2
測試代碼:
(代碼來源:《python極客項目編程》第五章)

import sys, argparse import math import numpy as np import matplotlib.pyplot as plt import matplotlib.animation as animation from scipy.spatial.distance import squareform, pdist, cdist from numpy.linalg import normwidth, height = 640, 480class Boids:"""class that represents Boids simulation"""def __init__(self, N):"""initialize the Boid simulation"""# initial position and velocitiesself.pos = [width/2.0, height/2.0] + 10*np.random.rand(2*N).reshape(N, 2)# normalized random velocitiesangles = 2*math.pi*np.random.rand(N)self.vel = np.array(list(zip(np.sin(angles), np.cos(angles))))self.N = N# minimum distance of approachself.minDist = 25.0# maximum magnitude of velocities calculated by "rules"self.maxRuleVel = 0.03# maximum magnitude of the final velocityself.maxVel = 2.0def tick(self, frameNum, pts, beak):"""Update the simulation by one time step."""# get pairwise distancesself.distMatrix = squareform(pdist(self.pos))# apply rules:self.vel += self.applyRules()self.limit(self.vel, self.maxVel)self.pos += self.velself.applyBC()# update datapts.set_data(self.pos.reshape(2*self.N)[::2],self.pos.reshape(2*self.N)[1::2])vec = self.pos + 10*self.vel/self.maxVelbeak.set_data(vec.reshape(2*self.N)[::2],vec.reshape(2*self.N)[1::2])def limitVec(self, vec, maxVel):"""limit the magnitide of the 2D vector"""mag = norm(vec)if mag > maxVel:vec[0], vec[1] = vec[0]*maxVel/mag, vec[1]*maxVel/magdef limit(self, X, maxVel):"""limit the magnitide of 2D vectors in array X to maxValue"""for vec in X:self.limitVec(vec, maxVel)def applyBC(self):"""apply boundary conditions"""deltaR = 2.0for coord in self.pos:if coord[0] > width + deltaR:coord[0] = -deltaRif coord[0] < - deltaR:coord[0] = width + deltaRif coord[1] > height + deltaR:coord[1] = - deltaRif coord[1] < - deltaR:coord[1] = height + deltaRdef applyRules(self):# apply rule #1: SeparationD = self.distMatrix < 25.0vel = self.pos * D.sum(axis=1).reshape(self.N, 1) - D.dot(self.pos)self.limit(vel, self.maxRuleVel)# distance threshold for alignment (different from separation)D = self.distMatrix < 50.0# apply rule #2: Alignmentvel2 = D.dot(self.vel)self.limit(vel2, self.maxRuleVel)vel += vel2# apply rule #3: Cohesionvel3 = D.dot(self.pos) - self.posself.limit(vel3, self.maxRuleVel)vel += vel3return veldef buttonPress(self, event):"""event handler for matplotlib button presses"""# print('run')# left-click to add a boidif event.button is 1:print('left button')self.pos = np.concatenate((self.pos, np.array([[event.xdata, event.ydata]])), axis=0)# generate a random velocityangles = 2*math.pi*np.random.rand(1)v = np.array(list(zip(np.sin(angles), np.cos(angles))))self.vel = np.concatenate((self.vel, v), axis=0)self.N += 1# right-click to scatter boidselif event.button is 3:print('right button')# add scattering velocityself.vel += 0.1*(self.pos - np.array([[event.xdata, event.ydata]]))def tick(frameNum, pts, beak, boids):# print frameNum"""update function for animation"""boids.tick(frameNum, pts, beak)return pts, beak# main() function def main():# use sys.argv if neededprint('starting boids...')parser = argparse.ArgumentParser(description="Implementing Craig Reynold's Boids...")# add argumentsparser.add_argument('--num-boids', dest='N', required=False)args = parser.parse_args()# set the initial number of boidsN = 100if args.N:N = int(args.N)# create boidsboids = Boids(N)# set up plotfig = plt.figure()ax = plt.axes(xlim=(0, width), ylim=(0, height))pts, = ax.plot([], [], markersize=10, c='k', marker='o', ls='None')beak, = ax.plot([], [], markersize=4, c='r', marker='o', ls='None')# add a "button press" event handlerfig.canvas.mpl_connect("button_press_event", boids.buttonPress)anim = animation.FuncAnimation(fig, tick, fargs=(pts, beak, boids), interval=50)plt.show()# call main if __name__ == '__main__':main()

正常運(yùn)行,但是點(diǎn)擊鼠標(biāo)無反應(yīng)。

思路:
首先,我想到的原因是matplotlib的UI交互部分可能已過時或已修改過。所以我谷歌了下matplotlib的UI交互功能實(shí)現(xiàn)。找到了這個網(wǎng)頁(http://www.guofei.site/2017/09/26/matplotlib3.html)
這個網(wǎng)頁寫的比較清楚,而且配有例子,所以我單獨(dú)新建一個文件測試這個網(wǎng)頁上的兩個例子。兩個例子都是可以正常運(yùn)行的。這就令我十分好奇,因為源代碼中需要判斷的是 event.button 這個變量,所以我就將例子做了下修改,只輸出 event.button 變量。結(jié)果如下
測試代碼:

import matplotlib.pyplot as plt import numpy as npfig, ax = plt.subplots() x = np.linspace(0, 10, 1000) y = np.sin(x) line = ax.plot(x, y)[0]def on_key_press(event):# print(event.name)print(event.button)print(type(event.button))print(event.button is 1)print(event.button == 1)fig.canvas.mpl_disconnect(fig.canvas.manager.key_press_handler_id) # 取消默認(rèn)快捷鍵的注冊 fig.canvas.mpl_connect('button_press_event', on_key_press) plt.show()

結(jié)果當(dāng)運(yùn)行代碼后,我點(diǎn)擊鼠標(biāo)左鍵,輸出卻是:

1 <class 'int'> False True

這時我突然想起之前看到的 is 和 == 是有區(qū)別的。 is 判斷的是前后兩個值的地址是否相同,而 == 判斷的才是前后兩個值是否相同,如下:

>>> a = 1 >>> b = 1.0 >>> a is b False >>> a == b True >>> id(a) 1356033504 >>> id(b) 1802191773368

所以只需要將源代碼中的 is 換為 == ,就可以創(chuàng)建和驅(qū)散鳥群了。

總結(jié):
通過這個模擬鳥群的代碼,學(xué)習(xí)到了在python中用matplotlib實(shí)現(xiàn)UI交互功能及 is 和 == 的區(qū)別。

總結(jié)

以上是生活随笔為你收集整理的python3环境下用matplotlib库实现UI交互的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。