How to add time-varying title for Python matplotlib.animation? - python

I am sorry for my poor English.
I have a matrix datas (10000 times 5000). It includes 10000 cases of data and the dimension of each data is 5000.
I want to make an animation to show each data one after another.
Following Code 1 works well.
(Code 1)
import matplotlib.pyplot as plt
import matplotlib.animation as animation
fig = plt.figure()
ims = []
for i in range(10000):
im = plt.plot(masks[i,:])
ims.append(im)
ani = animation.ArtistAnimation(fig, ims, interval=10)
plt.show()
ani.save('output.mp4', writer="ffmpeg")
I want to add the time-varying title to know which data (data index) is shown at a certain time.
And I wrote the following Code 2.
(Code 2)
import matplotlib.pyplot as plt
import matplotlib.animation as animation
fig = plt.figure()
ims = []
for i in range(10000):
im = plt.plot(masks[i,:])
tl = 'Data number:' + str(i+1) # ***added***
plt.title(tl) # ***added***
ims.append(im)
ani = animation.ArtistAnimation(fig, ims, interval=10)
plt.show()
ani.save('output.mp4', writer="ffmpeg")
However, I got an animation whose title is always 'Data number: 10000'.
How can I write the code to add the time-varying title?
I wrote plt.title(tl) before im = plt.plot(masks[i,:]) but nothing changed. Thank you for your help.
My environments are;
Python 3.6.9
matplitlib 3.3.3

We can imitate the figure title by annotating an axes object:
#test data generation
import numpy as np
np.random.seed(123)
masks = np.random.randn(10, 15)
#the animation routine starts here
import matplotlib.pyplot as plt
import matplotlib.animation as animation
fig, ax = plt.subplots()
ims = []
#iterating over the array
for i in range(masks.shape[0]):
#obtaining the Line2D object representing the line plot
im, = ax.plot(masks[i,:], color="blue")
#creating a centered annotation text above the graph
ann = ax.annotate(f"This is frame {i:.0f}.", (0.5, 1.03), xycoords="axes fraction", ha="center")
#collecting both objects for the animation
ims.append([im, ann])
ani = animation.ArtistAnimation(fig, ims, interval=300, repeat=False)
plt.show()

Related

Plot the last point with a different color in a matplotlib animation

I am trying to run the following code to display a number of points on a graph:
import numpy as np
import matplotlib
#matplotlib.use("Agg")
import matplotlib.pyplot as plt
import matplotlib.animation as animation
def update_point_on_graph(num, data, point):
point.set_data(data[..., :num])
return point,
# Set up formatting for the movie files
plt.rcParams['animation.ffmpeg_path'] = 'C:\\FFmpeg\\bin\\ffmpeg.exe'
Wrt = animation.writers['ffmpeg']
writer = Wrt(fps=5, metadata=dict(artist='Me'), bitrate=1800)
figure = plt.figure()
data_points = np.random.rand(2, 10)
point_graph, = plt.plot([], [], 'bo')
plt.xlim(0, 1)
plt.ylim(0, 1)
point_animation = animation.FuncAnimation(figure, update_point_on_graph, 25, fargs=(data_points, point_graph), interval=50, blit=True)
point_animation.save('C:\\Temp\\lines.mp4', writer=writer)
I would like to show the most recent point displayed by the animation at any point in time in red instead of blue, so it's easier to see where it is compared to the points that have already been put on the graph. Any suggestions are appreciated,
thanks

matplotlib is returning empty plot

Click Here for the image
trying to plot an animated line chart in python. Why is this code returning to a blank white plot ? a guidance would be appreciated. And also if there is a better way to draw an animated line chart in Python, please suggest.Thank you.
from matplotlib import pyplot as plt
from matplotlib.animation import FuncAnimation
import numpy as np
x_data=[]
y_data =[]
fig,ax = plt.subplots()
ax.set_xlim(0,100)
ax.set_ylim(0,12)
line, = ax.plot(0,0)
def update(i):
x_data.append(i*10)
y_data.append(i)
line.set_xdata(x_data)
line.set_ydata(y_data)
return line,
animation = FuncAnimation(fig,func = update, frames = np.arange(0,10,0.01), interval =200)
plt.show()
The code works for me, but is very slow because you have added 1000 frames at 200ms intervals, so the full animation takes 200 seconds to complete.
You need the imports at the top (and the appropriate libraries installed)
from matplotlib import pyplot as plt
from matplotlib.animation import FuncAnimation
import numpy as np
x_data = []
y_data = []
fig, ax = plt.subplots()
ax.set_xlim(0, 100)
ax.set_ylim(0, 12)
line, = ax.plot(0, 0)
def update(i):
x_data.append(i*10)
y_data.append(i)
line.set_xdata(x_data)
line.set_ydata(y_data)
return line,
animation = FuncAnimation(fig,func = update, frames = np.arange(0, 10, 0.01), interval = 2)
plt.show()
I have set the interval to 2ms in the above code to show a faster animation.

How to create a video that plots the scatter plots one by one using python?

I'm plotting some data as scatter plots which is overlaid on an image. I would like to make an animation of this by plotting one scatter point at a time. This is the code I have right now using and editing the answer from here:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
x = random.sample(range(0, 287), 20)
y = random.sample(range(0, 380), 20)
size = [20 for x in range(20)]
colors = ["r" for x in range(20)]
cm = plt.get_cmap('jet')
fig = plt.figure(figsize=(18,9))
graph = plt.scatter([], [],marker='+')
url = 'https://raw.githubusercontent.com/kornelski/pngquant/master/test/img/test.png'
im = plt.imread(url)
def animate(i):
implot = plt.imshow(im)
graph.set_offsets(np.vstack((x[:i+1], y[:i+1])).T)
graph.set_sizes(size[:i])
graph.set_facecolors(colors[:i+1])
return graph
ani = FuncAnimation(fig, animate, repeat=False, interval=0.1)
plt.show()
There are two things I would like help with.
I would like the color of my scatterplot to change based on a third variable, i.e use a cmap. However, the set_facecolors does not accept such an argument.
When I try to save my animation using ani.save('files/animation.gif',writer='imagemagick', fps=60) my jupyter notebook crashes.
Can someone help me?
The background image of the graph is drawn by adding ax. The color map is also created according to the number of data, 20, and a list is created so that each color can be displayed. Since the coordinates of the image and the coordinate basis of the graph are different, the y-axis is set in the opposite direction.
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
import random
from PIL import Image
import urllib.request
random.seed(20210702)
N = 20
x = random.sample(range(0, 380), N)
y = random.sample(range(0, 287), N)
size = [20 for x in range(N)]
colors = []
cm = plt.get_cmap('jet', N)
fig,ax = plt.subplots(figsize=(9, 4.5))
plt.xlim(0, 380)
plt.ylim(287, 0)
graph = ax.scatter([], [], marker='+')#
url = 'https://raw.githubusercontent.com/kornelski/pngquant/master/test/img/test.png'
im = Image.open(urllib.request.urlopen(url))
print(im.size)
def animate(i):
ax.imshow(im)
graph.set_offsets(np.vstack((x[:i+1], y[:i+1])).T)
graph.set_sizes(size[:i+1])
colors.append(cm(i))
graph.set_facecolors(colors)
return graph
ani = FuncAnimation(fig, animate, frames=20, repeat=False, interval=200)
plt.show()

Updating a matplotlib graph dynamically

I am trying to dynamically update a matplotlib from a .txt file that periodically updates.
For this, I used the following tutorial.
https://pythonprogramming.net/python-matplotlib-live-updating-graphs/
The .txt file looks like such
1,2
2,3
3,6
4,9
5,4
6,7
7,7
8,4
9,3
10,10
The code looks like such:
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import time
fig = plt.figure()
ax1 = fig.add_subplot(1,1,1)
def animate(i):
pullData = open("sampleText.txt","r").read()
dataArray = pullData.split('\n')
xar = []
yar = []
for eachLine in dataArray:
if len(eachLine)>1:
x,y = eachLine.split(',')
xar.append(int(x))
yar.append(int(y))
ax1.clear()
ax1.plot(xar,yar)
ani = animation.FuncAnimation(fig, animate, interval=1000)
plt.show()
This output a figure with these points plotted.
When I update with a new line, such as 11,15, and save there is no updated figure.
How can I make this update to the current figure as a new line is added to the .txt file?
I have tried some of the solutions to these questions asked on stackoverflow without success:
live updating with matplotlib
What is the currently correct way to dynamically update plots in Jupyter/iPython?
I created the code with the understanding that the intent of the question was to draw a graph based on the row-by-row data by retrieving the values from an updated, localized text file. The main points that I modified are the initial settings and updating the values in the animation function.
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import time
from matplotlib.animation import PillowWriter
#from IPython.display import HTML
pullData = open("sampleText.txt","r").read()
dataArray = pullData.split('\n')
frm = len(dataArray)
fig = plt.figure()
ax1 = plt.axes(xlim=(0, size), ylim=(0, size))
line, = ax1.plot([],[], 'r-', lw=3)
xar = []
yar = []
def animate(i):
if i < size:
x,y = dataArray[i].split(',')
xar.append(int(x))
yar.append(int(y))
line.set_data(xar, yar)
ax1.set_ylim(0, max(yar)+3)
return line
ani = animation.FuncAnimation(fig, animate, frames=frm, interval=200, repeat=False)
ani.save('plot_ani_test.gif', writer='pillow')
# jupyter lab
# plt.close()
# HTML(ani.to_html5_video())

How can I get my saved mp4 to exactly match the output of plot.show()?

When I try to save the results of an animation to mp4 using ffmpeg, I am getting a jumbled mess.
plt.show() shows exactly what I want it to show in the animation. However, when I save it using ffmpeg, the result is very different from what plt.show() returns. I have tried various arguments for fps etc. but nothing has helped.
%matplotlib
import pandas as pd
import matplotlib as mpl ## uncomment this if you are running this on a Mac
#mpl.use('TkAgg') ## and want to use blit=True
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import numpy as np
import csv
people = ('','Jim', 'Dan')
plt.rcdefaults()
fig, ax = plt.subplots()
y_pos = np.arange(len(people))
ax.set_xlim(0,10)
ax.set_yticks(y_pos)
ax.set_yticklabels(people)
ax.invert_yaxis()
ax.set_xlabel('Skill')
titleList=['Basketball','Hockey','Baseball']
df=[[0,5,7],[0,4,9],[0,2,6]]
def animate(i):
# Example data
while i<3:
ax.set_yticks(y_pos)
ax.set_yticklabels(people)
ax.set_xlabel(titleList[i])
performance=df[i]
title = ax.text(0.5,0.95,str(titleList[i]), bbox={'facecolor':'w', 'alpha':0.5, 'pad':5},transform=ax.transAxes, ha="center")
rects = ax.barh(y_pos, performance, align='center',
color='blue', ecolor='None')
return [rect for rect in rects] + [title]
ani = animation.FuncAnimation(fig,animate, frames=3, blit=True
,interval=2000,repeat=False)
plt.rcParams['animation.ffmpeg_path'] = 'C:\\ffmpeg\\bin\\ffmpeg.exe'
Writer = animation.writers['ffmpeg']
ani.save('test.mp4')
plt.show()
The result is a very fast video where all the data gets written over (similar to the plt.show() results when blit=False).

Categories

Resources