问题描述
已知的错误是在线程为多线程时绘制窗口的 plt.pause ,而另一个线程需要窗口绘制点,从而导致反应卡住.
Known bugs are when plots the window's plt.pause while the thread is multithreaded, and the other thread needs windows to draw points, causing the reaction to get stuck.
- 有什么方法可以在我的窗口中获得绘制点的效果动态显示,即点一步一步绘制.或者其他允许斧头窗口内容自动刷新的方式.
我认为主要问题是由命令plt.pause"引起的
I think the main problem is caused by the command "plt.pause"
#-*-coding:utf-8-*-
from matplotlib.patches import Circle
import matplotlib.pyplot as plt
import xlrd
import numpy as np
from matplotlib.animation import FuncAnimation
import matplotlib.ticker as mticker
import cartopy.crs as ccrs
from cartopy.mpl.gridliner import LONGITUDE_FORMATTER, LATITUDE_FORMATTER
import time
from matplotlib.offsetbox import AnnotationBbox,OffsetImage
from PIL import Image
import random
from time import ctime,sleep
import threading
#地图可视化
fig=plt.figure(figsize=(20,10))
ax = plt.axes(projection=ccrs.PlateCarree())
ax.coastlines()
ax.stock_img()
gl = ax.gridlines(crs=ccrs.PlateCarree(), draw_labels=True,
linewidth=2, color='gray', alpha=15, linestyle='--')
gl.xlabels_top = False
gl.ylabels_left = False
gl.xlines = False
gl.xlocator = mticker.FixedLocator([-180, -45, 0, 45, 180])
gl.xformatter = LONGITUDE_FORMATTER
gl.yformatter = LATITUDE_FORMATTER
gl.xlabel_style = {'size': 15, 'color': 'gray'}
gl.xlabel_style = {'color': 'red', 'weight': 'bold'}
img=Image.open(r'E:\python_file\untitled\p.png')
imagebox=OffsetImage(img,zoom=0.05)
imagebox.image.axes=ax
ab=AnnotationBbox(imagebox,[55,10],pad=0,frameon=False)
ax.add_artist(ab)
ac=AnnotationBbox(imagebox,[63,0],pad=0,frameon=False)
ax.add_artist(ac)
ad=AnnotationBbox(imagebox,[70,-10],pad=0,frameon=False)
ax.add_artist(ad)
#============================================#攻击
tolerance=1
x_m1,y_m1=random.randint(-180,180),random.randint(-90,90)
v_m1=170
x_m2,y_m2=random.randint(-180,180),random.randint(-90,90)
v_m2=v_m1
x_m3,y_m3=random.randint(-180,180),random.randint(-90,90)
v_m3=v_m1
x_m4,y_m4=55,10
x_m5,y_m5=63,0
x_m6,y_m6=70,-10
class target():
"""docstring for target"""
def __init__(self, x, y):
self.x = x
self.y = y
target1=target(x_m4,y_m4)
target2=target(x_m5,y_m5)
target3=target(x_m6,y_m6)
v=v_m1
class missile(threading.Thread):
"""docstring for missile"""
def __init__(self, x, y,name):
super(missile,self).__init__()
self.x = x
self.y = y
self.name=name
def forward(self, v, target1):
"""docstring for forward"""
if self.x < target1.x:
alpha = np.arctan((target1.y - self.y) / (target1.x - self.x))
elif self.x > target1.x:
alpha = np.pi + np.arctan((target1.y - self.y) / (target1.x - self.x))
elif self.x == target1.x and self.y < target1.y:
alpha = np.pi / 2
else:
alpha = -np.pi / 2
self.x = self.x + v * 0.01 * np.cos(alpha)
self.y = self.y + v * 0.01 * np.sin(alpha)
return self.x, self.y
def distance(self, target1):
"""docstring for distance"""
return np.sqrt((self.x - target1.x) ** 2 + (self.y - target1.y) ** 2)
def run(self):
while True:
if self.distance(target1)<self.distance(target2) and self.distance(target1)<self.distance(target3):
if self.distance(target1)<tolerance:
print ("collision")
break
else:
self.x,self.y=self.forward(v,target1)
if self.distance(target2)<self.distance(target1) and self.distance(target2)<self.distance(target3):
if self.distance(target2)<tolerance:
print ("collision")
break
else:
self.x,self.y=self.forward(v,target2)
if self.distance(target3)<self.distance(target2) and self.distance(target3)<self.distance(target1):
if self.distance(target3)<tolerance:
print ("collision")
break
else:
self.x,self.y=self.forward(v,target3)
print "qian jin"
plt.plot(self.x, self.y, 'bx')
print "ok2"
plt.pause(0.1)#the commond
m2=missile(x_m2,y_m2,'mm')
m1=missile(x_m1,y_m1,'mn')
m3=missile(x_m3,y_m3,'md')
m1.start()
m2.start()
m3.start()
plt.show()
这是所有代码
推荐答案
您可以尝试
fig.canvas.flush_events()
plt.pause() 的原因是因为当 matplotlib 绘图时,它首先生成绘图所需的结构,然后更新屏幕.但是,如果它不断获取新数据进行绘图,则它永远不会更新屏幕(繁忙的绘图).因此,暂停几分之一秒就可以让 matplotlib 有时间更新屏幕.图的flush_events函数强制matplotlib在没有停顿的情况下更新屏幕.
The reason for the plt.pause() is because when matplotlib plots it first generates the structure needed for the plot and then updates the screen. But if it continuously gets new data to plot it never updates the screen (to busy plotting). Therefore, pausing just a fraction of a second gives matplotlib time to update the screen. The flush_events function of the figure forces matplotlib to update the screen without the pause.
这篇关于python ax窗口内容被自动刷新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!