Manipulating and animating matplotlib graphics

I use matplotlib to animate the movements of the planets around the star. I draw a simple little circle that represents a planet, then I use funcanimation with the animate () function, which changes the center of the circles each time, as is done on this website: https://nickcharlton.net/posts/drawing-animating -shapes-matplotlib.html .

Now I'm trying to use an image file instead of a circle, but I barely know how to draw an image on a plot and really don't see how I can make it move on.

Any ideas?

thanks

0
source share
2 answers

Something like this will work:

import matplotlib.pyplot as plt import numpy as np from matplotlib.image import BboxImage from matplotlib.transforms import Bbox, TransformedBbox # make figure + Axes fig, ax = plt.subplots() # make initial bounding box bbox0 = Bbox.from_bounds(0, 0, 1, 1) # use the `ax.transData` transform to tell the bounding box we have given # it position + size in data. If you want to specify in Axes fraction # use ax.transAxes bbox = TransformedBbox(bbox0, ax.transData) # make image Artist bbox_image = BboxImage(bbox, cmap=plt.get_cmap('winter'), norm=None, origin=None, **kwargs ) # shove in some data a = np.arange(256).reshape(1, 256)/256. bbox_image.set_data(a) # add the Artist to the Axes ax.add_artist(bbox_image) # set limits ax.set_xlim(0, 10) ax.set_ylim(0, 10) # loop over new positions for j in range(50): x = j % 10 y = j // 10 # make a new bounding box bbox0 = Bbox.from_bounds(x, y, 1, 1) bbox = TransformedBbox(bbox0, ax.transData) bbox_image.bbox = bbox # re-draw the plot plt.draw() # pause so the gui can catch up plt.pause(.1) 

This is probably a little more complicated than necessary, and you really need to use animation frames, not pause .

0
source

I want to give you +1, but my reputation still does not allow it. Thank you very much for the code, I managed to place the imported image in the artist you are using by changing this line:

 bbox_image.set_data(mpimg.imread("C:\\image.png")) 

note I added this too

 Import matplotlib.image as mpimg 

But something else fails when I try to use funcanimation for animation, I get an error message, here is my code (yours changed):

 import matplotlib.pyplot as plt import numpy as np from matplotlib.image import BboxImage from matplotlib.transforms import Bbox, TransformedBbox import matplotlib.image as mpimg from matplotlib import animation # make figure + Axes fig, ax = plt.subplots() # make initial bounding box bbox0 = Bbox.from_bounds(0, 0, 1, 1) # use the `ax.transData` transform to tell the bounding box we have given # it position + size in data. If you want to specify in Axes fraction # use ax.transAxes bbox = TransformedBbox(bbox0, ax.transData) # make image Artist bbox_image = BboxImage(bbox, cmap=plt.get_cmap('winter'), norm=None, origin=None ) bbox_image.set_data(mpimg.imread("C:\\icon-consulting.png")) # add the Artist to the Axes ax.add_artist(bbox_image) # set limits ax.set_xlim(-10, 10) ax.set_ylim(-10, 10) def animate(i): bbox0 = Bbox.from_bounds(i, i, 1, 1) bbox = TransformedBbox(bbox0, ax.transData) bbox_image.bbox = bbox return bbox_image anim = animation.FuncAnimation(fig, animate, frames=100000, interval=20, blit=True) plt.show() 

This tells me Error: the "BboxImage" object is not iterable I assume that only part of the position of this BboxImage should be returned I used to do this with Line2D objects, adding to whom, for example: return lineobject, this means that only the first element of the tuple will be returned but I don’t see how this can be done using BboxImage

Actually, I can just use the loop, as you did, but maybe you know how to adapt it to function?

Edit:

I changed your code again using the bbox method:

 for j in range(5000): x = 2*np.sin(np.radians(j)) y = 2*np.cos(np.radians(j)) # make a new bounding box bbox0.set_points([[x,y],[x+1,y+1]]) # re-draw the plot plt.draw() # pause so the gui can catch up plt.pause(0.1) 

I can then convert this to use the functionalization as follows:

 def animate(i): x = 2*np.sin(np.radians(i)) y = 2*np.cos(np.radians(i)) # make a new bounding box bbox0.set_points([[x,y],[x+1,y+1]]) return bbox0.get_points() anim = animation.FuncAnimation(fig, animate, frames=100000, interval=20, blit=True) plt.show() 

This gives me an error: the 'list' object does not have the 'axes' attributes, this is the return that I do in the animate function, the return value must be converted somehow, I think ... Do you know how I can do this? Thanks

0
source

Source: https://habr.com/ru/post/1244956/


All Articles