I'm seeking how to change an alpha value dynamically which are already plotted.
This is a kind of sample code I want to implement, but I know it is a wrong writing.
import matplotlib.pyplot as pltfig = plt.subplot(1, 1)for rate in [0.1 * x for x in range(10, -1, -1)]:plt.plot(range(0, 5), range(0, 5), color="r", alpha=rate)plt.pause(0.1)plt.show()
The purpose of this sample code is that I want to decrease the alpha as the processing go on and make the line vanish.
Does somebody know a way to accomplish like this problem?
Thank you.
I thought, that you wanted to control the alpha
value for each point individually, so I set out to do this (based on this):
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from matplotlib.collections import LineCollectionclass Vanishing_Line(object):def __init__(self, n_points, tail_length, rgb_color):self.n_points = int(n_points)self.tail_length = int(tail_length)self.rgb_color = rgb_colordef set_data(self, x=None, y=None):if x is None or y is None:self.lc = LineCollection([])else:# ensure we don't start with more points than we wantx = x[-self.n_points:]y = y[-self.n_points:]# create a list of points with shape (len(x), 1, 2)# array([[[ x0 , y0 ]],# [[ x1 , y1 ]],# ...,# [[ xn , yn ]]])self.points = np.array([x, y]).T.reshape(-1, 1, 2)# group each point with the one following it (shape (len(x)-1, 2, 2)):# array([[[ x0 , y0 ],# [ x1 , y1 ]],# [[ x1 , y1 ],# [ x2 , y2 ]],# ...self.segments = np.concatenate([self.points[:-1], self.points[1:]],axis=1)if hasattr(self, 'alphas'):del self.alphasif hasattr(self, 'rgba_colors'):del self.rgba_colors#self.lc = LineCollection(self.segments, colors=self.get_colors())self.lc.set_segments(self.segments)self.lc.set_color(self.get_colors())def get_LineCollection(self):if not hasattr(self, 'lc'):self.set_data()return self.lcdef add_point(self, x, y):if not hasattr(self, 'points'):self.set_data([x],[y])else:# TODO: could use a circular buffer to reduce memory operations...self.segments = np.concatenate((self.segments,[[self.points[-1][0],[x,y]]]))self.points = np.concatenate((self.points, [[[x,y]]]))# remove points if necessary:while len(self.points) > self.n_points:self.segments = self.segments[1:]self.points = self.points[1:]self.lc.set_segments(self.segments)self.lc.set_color(self.get_colors())def get_alphas(self):n = len(self.points)if n < self.n_points:rest_length = self.n_points - self.tail_lengthif n <= rest_length:return np.ones(n)else:tail_length = n - rest_lengthtail = np.linspace(1./tail_length, 1., tail_length)rest = np.ones(rest_length)return np.concatenate((tail, rest))else: # n == self.n_pointsif not hasattr(self, 'alphas'):tail = np.linspace(1./self.tail_length, 1., self.tail_length)rest = np.ones(self.n_points - self.tail_length)self.alphas = np.concatenate((tail, rest))return self.alphasdef get_colors(self):n = len(self.points)if n < 2:return [self.rgb_color+[1.] for i in xrange(n)]if n < self.n_points:alphas = self.get_alphas()rgba_colors = np.zeros((n, 4))# first place the rgb color in the first three columnsrgba_colors[:,0:3] = self.rgb_color# and the fourth column needs to be your alphasrgba_colors[:, 3] = alphasreturn rgba_colorselse:if hasattr(self, 'rgba_colors'):passelse:alphas = self.get_alphas()rgba_colors = np.zeros((n, 4))# first place the rgb color in the first three columnsrgba_colors[:,0:3] = self.rgb_color# and the fourth column needs to be your alphasrgba_colors[:, 3] = alphasself.rgba_colors = rgba_colorsreturn self.rgba_colorsdef data_gen(t=0):"works like an iterable object!"cnt = 0while cnt < 1000:cnt += 1t += 0.1yield t, np.sin(2*np.pi*t) * np.exp(-t/100.)def update(data):"Update the data, receives whatever is returned from `data_gen`"x, y = dataline.add_point(x, y)# rescale the graph by large steps to avoid having to do it every time:xmin, xmax = ax.get_xlim()if x >= xmax:ax.set_xlim(xmin, 2*xmax)ax.figure.canvas.draw()return line,if __name__ == '__main__':n_points = 100tail_length = (3/4.)*n_pointsrgb_color = [0., 0.5, 1.0]time_pause = 0 # milisecondsx=np.linspace(0, 4*np.pi, 2*n_points)y=np.cos(x)line = Vanishing_Line(n_points, tail_length, rgb_color)fig, ax = plt.subplots()ax.add_collection(line.get_LineCollection())ax.set_xlim(0, 4*np.pi)ax.set_ylim(-1.1,1.1)ani = animation.FuncAnimation(fig, update, data_gen, blit=False,interval=time_pause, repeat=False)fig.show()mywriter = animation.FFMpegWriter(fps=30)ani.save('ani.mp4', writer=mywriter, dpi=600)
It should plot a graphic with a vanishing line (saved with tips from here, and converted from mp4 to gif online):
There appears to be a bug at the start of the animation shown in real time by python when saving the graph, as there appears a line from [10,0] to the first point.
That line does not appear on the saved animation and if you comment the two lines to save to graph that disappears.
I believe the animation saving is running before the animation display, and thus the last point from the saving run is shown on the start of the display run.