Вопрос-Ответ

How to update a plot in matplotlib

Как обновить график в matplotlib

У меня возникли проблемы с перерисовкой рисунка здесь. Я разрешаю пользователю указывать единицы измерения в масштабе времени (ось x), а затем я пересчитываю и вызываю эту функцию plots(). Я хочу, чтобы график просто обновлялся, а не добавлял другой график к рисунку.

def plots():
global vlgaBuffSorted
cntr()

result = collections.defaultdict(list)
for d in vlgaBuffSorted:
result[d['event']].append(d)

result_list = result.values()

f = Figure()
graph3 = f.add_subplot(211)
graph2 = f.add_subplot(212,sharex=graph3)

for item in result_list:
tL = []
vgsL = []
vdsL = []
isubL = []
for dict in item:
tL.append(dict['time'])
vgsL.append(dict['vgs'])
vdsL.append(dict['vds'])
isubL.append(dict['isub'])
graph3.plot(tL,vdsL,'bo',label='a')
graph3.plot(tL,vgsL,'rp',label='b')
graph2.plot(tL,isubL,'b-',label='c')

plotCanvas = FigureCanvasTkAgg(f, pltFrame)
toolbar = NavigationToolbar2TkAgg(plotCanvas, pltFrame)
toolbar.pack(side=BOTTOM)
plotCanvas.get_tk_widget().pack(side=TOP)
Переведено автоматически
Ответ 1

По сути, у вас есть два варианта:


  1. Делайте в точности то, что вы делаете в данный момент, но вызывайте graph3.clear() и graph2.clear() перед пересчетом данных. Это самый медленный, но самый простой и надежный вариант.


  2. Вместо реплоттинга вы можете просто обновить данные объектов plot. Вам нужно будет внести некоторые изменения в свой код, но это должно быть намного, намного быстрее, чем повторять что-либо каждый раз. Однако форма данных, которые вы строите, не может измениться, и если диапазон ваших данных меняется, вам нужно будет вручную сбросить ограничения по осям x и y.


Чтобы привести пример второго варианта:

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 6*np.pi, 100)
y = np.sin(x)

# You probably won't need this if you're embedding things in a tkinter plot...
plt.ion()

fig = plt.figure()
ax = fig.add_subplot(111)
line1, = ax.plot(x, y, 'r-') # Returns a tuple of line objects, thus the comma

for phase in np.linspace(0, 10*np.pi, 500):
line1.set_ydata(np.sin(x + phase))
fig.canvas.draw()
fig.canvas.flush_events()
Ответ 2

Вы также можете поступить следующим образом: это приведет к отображению случайных матричных данных размером 10x1 на графике за 50 циклов цикла for.

import matplotlib.pyplot as plt
import numpy as np

plt.ion()
for i in range(50):
y = np.random.random([10,1])
plt.plot(y)
plt.draw()
plt.pause(0.0001)
plt.clf()
Ответ 3

У меня это сработало:

from matplotlib import pyplot as plt
from IPython.display import clear_output
import numpy as np
for i in range(50):
clear_output(wait=True)
y = np.random.random([10,1])
plt.plot(y)
plt.show()
Ответ 4

У меня это сработало. Каждый раз повторно вызывает функцию, обновляющую график.

import matplotlib.pyplot as plt
import matplotlib.animation as anim

def plot_cont(fun, xmax):
y = []
fig = plt.figure()
ax = fig.add_subplot(1,1,1)

def update(i):
yi = fun()
y.append(yi)
x = range(len(y))
ax.clear()
ax.plot(x, y)
print i, ': ', yi

a = anim.FuncAnimation(fig, update, frames=xmax, repeat=False)
plt.show()

"fun" - это функция, которая возвращает целое число.
FuncAnimation будет повторно вызывать "update", он будет делать это "xmax" раз.

python matplotlib tkinter