我有一个python脚本,它连续循环,用户输入指示它从文件中获取数据,然后使用matplotlib绘制它。我的希望是让剧情出现并坚持(并继续保持互动),同时脚本继续在控制台中请求下一轮用户输入和绘图。因此,用户最终可能会打开几个完全正常运行的绘图窗口。
我实际上已经在我的python 2.7 anaconda构建中使用以下示例代码进行工作,该代码只是在每个循环中绘制一个随机数据集。
import sys
import matplotlib.pyplot as plt
import matplotlib
import numpy as np
print('matplotlib version: '+matplotlib.__version__)
version = sys.version_info[0]
def plot_data(data):
fig = plt.figure(figsize=(6,6))
plt.plot(data)
plt.ion()
plt.show()
plt.pause(0.001)
while True:
if version < 3:
option = raw_input('type (1) to plot next data, (q) to quit\n')
else:
option = input('type (1) to plot next data, (q) to quit\n')
if option == '1':
data = np.random.choice(1000,100, replace = False)
plot_data(data)
elif option == 'q':
break
使用我的python 3.6版本运行代码,该图显示但在非响应状态下被冻结,直到我返回控制台并输入q退出我的用户输入循环。在python 2.7中,绘图窗口通过多个输入循环和绘图调用完全起作用。所以我希望有人知道这里有什么不同。我正在打印matplotlib版本,看起来我的2.7和3.6环境都使用相同的matplotlib 2.0.2所以也许它在GUI处理程序中?
答案 0 :(得分:0)
我不确定使用while循环和plt.ion()
的问题的设置是否真的应该有效。至少对我来说使用python 2.7和matplotlib 2.1它没有
我希望这是可以预料到的,因为只要等待用户输入,应用程序就会冻结并变得无响应。
在任何情况下,由于混合控制台和GUI应用程序总是有点微妙,我会选择完全在GUI的事件循环中工作。
您可以将"key_press_event"
连接到"1"
和"q"
键,并在打开的matplotlib窗口中显示新数据。
import matplotlib.pyplot as plt
import numpy as np
fig = plt.figure(figsize=(6,6))
ax = plt.subplot(111)
def plot_data(ax, data):
ax.clear()
ax.plot(data)
ax.figure.canvas.draw_idle()
def press(event=None):
if event:
if event.key == "1":
data = np.random.choice(1000,100, replace = False)
plot_data(ax, data)
elif event.key == "q":
plt.close()
cid= fig.canvas.mpl_connect("key_press_event", press)
plt.show()
如果你想创建几个数字,这看起来像
import matplotlib.pyplot as plt
import numpy as np
def create_figure(data):
fig, ax = plt.subplots(figsize=(6,6))
ax.plot(data)
cid = fig.canvas.mpl_connect("key_press_event", press)
fig.show()
def plot_data():
data = np.random.choice(1000,100, replace = False)
create_figure(data)
def press(event=None):
if event:
if event.key == "1":
plot_data()
elif event.key == "q":
plt.close("all")
else:
plot_data()
press()
plt.show()
对于更复杂的输入,您可以创建一个小GUI,它收集输入并调用绘图功能。例如,可以为此目的使用Tkinter。
from Tkinter import * # use from tkinter import * if using python3
import matplotlib.pyplot as plt
import numpy as np
def create_figure(data):
fig, ax = plt.subplots(figsize=(6,6))
ax.plot(data)
fig.show()
def plot_data(n, amp):
try:
n = int(n)
amp = float(amp)
data = amp*np.random.rand(n)
create_figure(data)
except:
pass
def closeall():
for i in plt.get_fignums():
plt.close(i)
def create_input():
root = Tk()
Label(text="Number of datapoints").grid(row=1,column=0, sticky=W)
Label(text="Amplitude").grid(row=2,column=0, sticky=W)
tb1=Entry(root,textvariable=StringVar(root, value='24'))
tb1.grid(row=1,column=1, sticky=W+E)
tb2=Entry(root,textvariable=StringVar(root, value='6'))
tb2.grid(row=2,column=1, sticky=W+E)
b1=Button(root,text=" Plot ",command= lambda : plot_data(tb1.get(),tb2.get()))
b1.grid(row=4,column=1, sticky=W+E)
b2=Button(root,text="Close All",command=closeall)
b2.grid(row=5,column=1, sticky=W+E)
root.mainloop()
create_input()