#python #matplotlib #jupyter_notebook
Подскажите есть ли возможность в jupyter рисовать анимированные графики, вроде графика
загрузки процессора в реальном времени? Пытаюсь сделать мониторинг времени ответа сервера
на пинг.
Разбираюсь с matplotlib, но то ли он такого не умеет, то ли я не нашел.
import subprocess
import re
from matplotlib import pyplot as plt
def ping(adress):
p = subprocess.Popen(["ping.exe",adress], stdout = subprocess.PIPE)
out = p.communicate()[0]
t = re.search(r'time=(\d*)',str(out))
time = t.group().replace('time=','') if t else '0'
return (time)
x=[0]
%matplotlib inline
for i in range(0,10):
x.append(ping('ya.ru'))
plt.plot(x)
График просчитывается весь и отрисовывается весь сразу, подскажите как сделать анимацию
и возможно ли вообще такое?
Ответы
Ответ 1
Можно так сделать:
import psutil
from datetime import datetime as dt
from collections import deque
import matplotlib.pyplot as plt
from matplotlib.dates import date2num
import matplotlib.animation as animation
%matplotlib notebook
N=600
x = deque([date2num(dt.now())], maxlen=N)
y = deque([0], maxlen=N)
fig, ax = plt.subplots(figsize=(8,3))
line, = ax.plot_date(x, y, marker="")
ax.spines['left'].set_visible(False)
ax.spines['bottom'].set_visible(False)
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
def get_data():
# return ping('ya.ru')
return psutil.cpu_percent(.15)
def animate(i):
x.append(date2num(dt.now()))
y.append(get_data())
ax.relim(visible_only=True)
ax.autoscale_view(True)
line.set_data(x, y)
ax.fill_between(x, -0.5, y, color='lightgrey')
return line,
ani = animation.FuncAnimation(fig, animate, interval=300)
#ani.save("d:/temp/test.gif", writer='imagemagick', fps=10)
plt.show()
Результат:
Ответ 2
в jupyter рисовать анимированные графики, вроде графика загрузки процессора в реальном
времени?
Рисуем фон и оси графика:
%matplotlib inline
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
line, = ax.plot([], [], color='g')
time_template = 'time = %s'
time_text = ax.text(0.05, 0.9, '', transform=ax.transAxes)
Создаём функцию, которая генерирует текущие значения (x, y):
import time
import psutil # !pip install psutil
def frames():
while True:
yield time.time(), psutil.cpu_percent(.15) # CPU % over the second
обновляем график и экран, используя значения полученные из frames():
import datetime as DT
from collections import deque
n = 1000
yy = deque([], maxlen=n)
xx = deque([], maxlen=n)
display_handle = display(None, display_id=True)
def animate(args):
xx.append(args[0])
yy.append(args[1])
line.set_data(xx, yy)
time_text.set_text(time_template % DT.datetime.fromtimestamp(args[0]))
ax.relim() # update axes limits
ax.autoscale_view(True, True, True)
display_handle.update(fig)
for x_y in frames():
animate(x_y)
Если вам не нужна поддержка Jupyter Lab или достаточно конечный цикл, который как
видео можно добавить, то вместо явного display_handler.update() и явного цикла, где
вручную animate() вызывается, можно использовать:
%matplotlib notebook
from matplotlib import animation
ani = animation.FuncAnimation(fig, animate, frames=frames)
и/или (конечное число кадров):
from IPython.display import HTML
HTML(ani.to_html5_video())