如何在matplotlib python中动态更改alpha值

如何在matplotlib python中动态更改alpha值,python,matplotlib,Python,Matplotlib,我正在寻找如何动态更改已绘制的alpha值 这是我想要实现的一种示例代码,但我知道这是一种错误的编写方法 import matplotlib.pyplot as plt fig = 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.sho

我正在寻找如何动态更改已绘制的alpha值

这是我想要实现的一种示例代码,但我知道这是一种错误的编写方法

import matplotlib.pyplot as plt

fig = 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()
这个示例代码的目的是,随着处理的进行,我希望减少alpha值,并使行消失

有人知道解决这个问题的方法吗?
谢谢。

您可以使用
set\u alpha
方法更新现有
Line2D
的alpha值。其想法是绘制一次直线,然后更新循环中的alpha

import matplotlib.pyplot as plt

fig = plt.subplot(111)
plt.ion()
line, = plt.plot(range(0, 5), range(0, 5), color="r", alpha=1)
for rate in [0.1 * x for x in range(10, -1, -1)]:
    line.set_alpha(rate)
    plt.draw()
    plt.pause(0.1)

plt.ioff()
plt.show()

我认为,您希望单独控制每个点的
alpha
值,因此我开始这样做(基于):

将numpy导入为np
将matplotlib.pyplot作为plt导入
将matplotlib.animation导入为动画
从matplotlib.collections导入LineCollection
类消失线(对象):
定义初始值(自身、n点、尾部长度、rgb颜色):
self.n_点=int(n_点)
self.tail\u length=int(tail\u length)
self.rgb_color=rgb_color
def set_数据(自身,x=无,y=无):
如果x为无或y为无:
self.lc=LineCollection([])
其他:
#确保我们一开始的分数不会超过我们想要的
x=x[-self.n_点:]
y=y[-self.n_点:]
#创建具有形状(len(x)、1、2)的点列表
#数组([[x0,y0]],
#[[x1,y1]],
#        ...,
#[[xn,yn]]]
self.points=np.array([x,y]).T.reformate(-1,1,2)
#将每个点与后面的一个点分组(形状(len(x)-1,2,2)):
#数组([[x0,y0],
#[x1,y1]],
#[[x1,y1],
#[x2,y2]],
#         ...
self.segments=np.concatenate([self.points[:-1],self.points[1:],
轴=1)
如果hasattr(self,“alphas”):
del self.alphas
如果hasattr(self,'rgba_colors'):
del self.rgba_颜色
#self.lc=LineCollection(self.segments,colors=self.get\u colors())
self.lc.set_段(self.segments)
self.lc.set\u color(self.get\u colors())
def get_LineCollection(自身):
如果不是hasattr(self,'lc'):
self.set_data()
返回自我信用证
def添加点(自身、x、y):
如果不是hasattr(self,“points”):
self.set_数据([x],[y])
其他:
#TODO:可以使用循环缓冲区来减少内存操作。。。
self.segments=np.concatenate((self.segments,[[self.points[-1][0],[x,y]]))
self.points=np.concatenate((self.points,[[[x,y]]]))
#如有必要,请删除点:
而len(self.points)>self.n_点:
self.segments=self.segments[1:]
self.points=self.points[1:]
self.lc.set_段(self.segments)
self.lc.set\u color(self.get\u colors())
def get_alphas(自身):
n=长度(自身点)
如果n
它应该绘制一个带有消失线的图形(使用提示保存,并从mp4在线转换为gif):

保存图形时,python实时显示的动画的开头似乎有一个bug,因为从[10,0]到第一个点出现了一条线

该行不会出现在保存的动画中,如果对要保存到图形的两行进行注释,则该行将消失


我相信动画保存是在动画显示之前运行的,因此保存运行的最后一点显示在显示运行的开始处。

谢谢!这是否意味着如果我想更改alpha值超过两个(我是说,超过两条不同的线),我必须保持每一条“线”吗对象?是的,但您可以将它们存储在列表中,并在列表上循环,因此实际上不需要太多的代码。如果您想更改图形中所有行的alpha,也可以只循环
plt.gca().lines
。哦,您还可以…另外,如果是生成器,则默认情况下,保存程序将只保存100帧。不知道为什么,但您可以通过不使用生成器并直接在update函数上计算新值,以及通过给
frames
一个ìnt`值来解决此问题。
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from matplotlib.collections import LineCollection

class 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_color

    def 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 want
            x = 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.alphas
            if 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.lc


    def 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_length
            if n <= rest_length:
                return np.ones(n)
            else:
                tail_length = n - rest_length
                tail = np.linspace(1./tail_length, 1., tail_length)
                rest = np.ones(rest_length)
                return np.concatenate((tail, rest))
        else: # n == self.n_points
            if 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.alphas

    def 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 columns
            rgba_colors[:,0:3] = self.rgb_color
            # and the fourth column needs to be your alphas
            rgba_colors[:, 3] = alphas
            return rgba_colors
        else:
            if hasattr(self, 'rgba_colors'):
                pass
            else:
                alphas = self.get_alphas()
                rgba_colors = np.zeros((n, 4))
                # first place the rgb color in the first three columns
                rgba_colors[:,0:3] = self.rgb_color
                # and the fourth column needs to be your alphas
                rgba_colors[:, 3] = alphas
                self.rgba_colors = rgba_colors
            return self.rgba_colors

def data_gen(t=0):
    "works like an iterable object!"
    cnt = 0
    while cnt < 1000:
        cnt += 1
        t += 0.1
        yield 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 = data
    line.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 = 100
    tail_length = (3/4.)*n_points
    rgb_color = [0., 0.5, 1.0]
    time_pause = 0 # miliseconds

    x=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)