Search code examples
pythonnumpymatplotlibanimationmatplotlib-animation

How to animate color filling inside rectangle using python and matplotlib?


I want to animate color inside rectangle on y axes, color filling should move up and down like the way peakmeter bar behaves. There is mistake in this code that i am not able to solve. please help me to solve this issue.

import matplotlib.pyplot as plt
import matplotlib.animation as animation
import random
import numpy


class AnimRect(object):
    '''Animate a rectangle'''
    def __init__(self):
        self.fig = plt.figure(figsize = (5,5))
        # create the axes
        self.ax = plt.axes(xlim=(0,100), ylim=(0,100), aspect='equal')
        # create rectangle
        self.rect = plt.Rectangle((0,0), 5, 50,
                                   fill=True, color='gold', ec='blue')
        self.ax.add_patch(self.rect)
        self.y=[]
        for i in range(100):
            x = random.randint(0, 30)
            self.y.append(x)
        self.y = numpy.array(self.y)
        # print(self.y,len(self.y))
        self.call_animation()
        plt.show()

    # animation function
    def animate(self, i):
        self.rect = self.ax.fill_between(0, self.y[i],0, color = 'red')
        return self.rect,

    def call_animation(self):
        # call the animator function
        self.anim = animation.FuncAnimation(self.fig, self.animate, frames=len(self.y), interval=0.1, blit=True, repeat=False)

def main():
    rect = AnimRect()

main()

It gives such error in console

idx, = np.nonzero(mask[:-1] != mask[1:]) IndexError: too many indices for array

Solution

  • Inside the animate function you should replace your line of code with this one:

    self.rect = self.ax.fill_between(x = (0, 5), y1 = 0, y2 = self.y[i], color = 'red')
    

    I link the documentation to fill_between method:

    x:    array (length N)
          The x coordinates of the nodes defining the curves. y1array (length N) or scalar
    
    y1:   array (length N) or scalar
          The y coordinates of the nodes defining the first curve. y2array (length N) or scalar, optional, default: 0
    
    y2:   array (length N) or scalar, optional, default: 0
          The y coordinates of the nodes defining the second curve.
    

    The issue with your code is that you specified x as int while it should be an array.