Skip to content Skip to sidebar Skip to footer

Manipulating And Animating An Image On A Matplotlib Plot

I'm using matplotlib to animate a planets movements around a star. I draw a simple small circle that represents the planet then i use funcanimation with an animate() function that

Solution 1:

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 positionsfor j inrange(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)

It is probably a bit more complicated than it needs to be and you really should use the animation framework rather than pause.

Solution 2:

I wanna give you a +1 but my reputation doesn't allow it yet. Thank's alot for the code, I succeeded in putting an imported image in the artist you use by modifying this line :

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

note I added this too

Import matplotlib.image as mpimg

But something's still amiss when I try to use funcanimation to animate this I get an error, here's my code (your's modified) :

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)


defanimate(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()

It tells me Error : 'BboxImage' object is not iterable I guess only the position part of this BboxImage should be returned I was used to doing this with Line2D objets by adding a coma, example : return lineobject, which means only the first element of the tuple will be returned, but I don't see how It can be done with BboxImage

In fact I can simply use the loop as you first did,but perhaps you know how to adapt this to funcanimation ?

Edit :

I modified your code again using a 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)

Then I can convert this to use funcanimation this way :

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 : 'list' object is has no attribute 'axes' it's the return I'm doing in the animate function, the returned value should be converted somehow I guess ... Do you know how I can do that ? Thanks

Post a Comment for "Manipulating And Animating An Image On A Matplotlib Plot"