多颜色渐隐动态散点图实现问题:为不同X值分配颜色
动态散点图:固定X值专属颜色+旧点淡出实现
需求如下:
- 绘制动态散点图,x1对应x=1,x2对应x=2,x3对应x=3;
- 为每个像素分配独特颜色(x1为红色,x2为蓝色,x3为绿色);
- 更新数据时,旧的散点数据逐渐淡出。
参考Stack Overflow上的示例代码修改后,无法为x=1、x=2、x=3这三个不同X值分别分配颜色,当前代码及效果如下:
import numpy as np import matplotlib.pyplot as plt import matplotlib.animation from matplotlib.colors import LinearSegmentedColormap from matplotlib.animation import PillowWriter fig, ax = plt.subplots() ax.set_xlabel('X Axis', size = 12) ax.set_ylabel('Y Axis', size = 12) ax.axis([0,4,0,1]) x_vals = [] y_vals = [] intensity = [] iterations = 100 t_vals = np.linspace(0,1, iterations) colors = [[0,0,1,0],[0,0,1,0.5],[0,0.2,0.4,1], [1,0.2,0.4,1]] cmap = LinearSegmentedColormap.from_list("", colors) scatter = ax.scatter(x_vals,y_vals, c=[], cmap=cmap, vmin=0,vmax=1) def get_new_vals(): x = np.arange(1,4) # TODO: ASSOCIATE COLOUR WITH EACH X VALUE y = np.random.rand(3) return list(x), list(y) def update(t): global x_vals, y_vals, intensity # Get intermediate points new_xvals, new_yvals = get_new_vals() x_vals.extend(new_xvals) y_vals.extend(new_yvals) # Put new values in your plot scatter.set_offsets(np.c_[x_vals,y_vals]) #calculate new color values intensity = np.concatenate((np.array(intensity)*0.96, np.ones(len(new_xvals)))) scatter.set_array(intensity) # Set title ax.set_title('Different colors for each x value') ani = matplotlib.animation.FuncAnimation(fig, update, frames=t_vals,interval=50) plt.show()

修改方案
核心思路是放弃单一colormap,直接维护每个点的RGBA颜色数组:根据x值确定点的基础颜色(红/蓝/绿),再通过强度值控制透明度,旧点的透明度随时间衰减。
修改后的代码:
import numpy as np import matplotlib.pyplot as plt import matplotlib.animation from matplotlib.animation import PillowWriter fig, ax = plt.subplots() ax.set_xlabel('X Axis', size=12) ax.set_ylabel('Y Axis', size=12) ax.axis([0, 4, 0, 1]) # 存储所有点的坐标和颜色 x_vals = [] y_vals = [] colors = [] iterations = 100 # 定义每个x对应的基础RGB颜色 x_color_map = { 1: [1, 0, 0], # 红色 2: [0, 0, 1], # 蓝色 3: [0, 1, 0] # 绿色 } # 初始化散点图,颜色初始为空 scatter = ax.scatter(x_vals, y_vals, c=colors) def get_new_vals(): x = np.arange(1, 4) y = np.random.rand(3) return list(x), list(y) def update(t): global x_vals, y_vals, colors # 获取新数据 new_xvals, new_yvals = get_new_vals() x_vals.extend(new_xvals) y_vals.extend(new_yvals) # 为新点添加对应颜色(初始透明度1) for x in new_xvals: base_rgb = x_color_map[x] colors.append(base_rgb + [1.0]) # RGBA格式 # 更新散点坐标 scatter.set_offsets(np.c_[x_vals, y_vals]) # 衰减旧点的透明度 if len(colors) > len(new_xvals): # 对除了新添加的点之外的所有旧点,透明度乘以衰减系数 for i in range(len(colors) - len(new_xvals)): colors[i][3] *= 0.96 # 更新散点颜色 scatter.set_color(colors) ax.set_title('不同X值对应专属颜色的动态散点图') ani = matplotlib.animation.FuncAnimation(fig, update, frames=iterations, interval=50) plt.show()
关键改动说明
- 颜色映射字典:用
x_color_map明确x=1/2/3对应的基础RGB颜色; - RGBA颜色维护:直接存储每个点的RGBA数组,新点初始透明度为1;
- 透明度衰减:每次更新时,对所有旧点的透明度乘以0.96,实现淡出效果;
- 放弃colormap:不再依赖
scatter.set_array()和colormap,直接用set_color()设置每个点的颜色。
这样就能实现每个固定X值的点保持专属颜色,同时旧点随时间逐渐淡出的效果。
内容的提问来源于stack exchange,提问作者Leo
相关产品推荐
相关产品推荐

