循环绘制散点图后添加连续色条的实现方法
如何给循环绘制的散点图添加连续色条
我来帮你搞定这个连续色条的问题~咱们先分析下你当前代码的问题:你是通过循环逐个绘制不同分组的散点,每个g都是独立的散点集合,而且你直接给每个分组指定了固定颜色,没有和一个统一的**颜色映射(colormap)以及数值范围(norm)**绑定起来。fig.colorbar()需要的是一个ScalarMappable对象(也就是关联了颜色映射和数值范围的对象),而你传入的单个散点对象满足不了这个要求,所以才会出问题。
下面给你两种解决方案,按需选择:
方法一:用Seaborn直接绘制(最简便)
其实Seaborn的scatterplot原生就支持基于连续变量的颜色映射,完全不用自己写循环,代码更简洁,还能自动处理色条:
import pandas as pd import seaborn as sns import numpy as np import matplotlib.pyplot as plt from matplotlib.colors import Normalize np.random.seed(42) df = pd.DataFrame(np.random.rand(2, 100), index=['S1','S2']).T tars = np.random.choice([0,0.3,0.5,0.8,1], 100) df = pd.concat([df, pd.Series(tars, name='group')], axis=1) fig = plt.figure(figsize=(10,8), dpi=300) ax = fig.add_subplot(1,1,1) # 直接用seaborn绘制,hue指定为连续的group列 sns.scatterplot( x='S1', y='S2', hue='group', data=df, palette='viridis', # 选你喜欢的配色 ax=ax ) # 调整色条(可选,默认已经有了) plt.colorbar(ax.collections[0], ax=ax, label='Group Value') plt.show()
这里的关键是把group作为连续变量传给hue,Seaborn会自动创建对应的颜色映射和色条,完全不用手动处理循环。
方法二:保留循环,手动创建ScalarMappable
如果你一定要用循环的方式绘制,那需要手动创建一个ScalarMappable对象,把数值范围和颜色映射绑定起来,再传给fig.colorbar():
import pandas as pd import numpy as np import matplotlib.pyplot as plt from matplotlib.colors import Normalize import matplotlib.cm as cm np.random.seed(42) df = pd.DataFrame(np.random.rand(2, 100), index=['S1','S2']).T tars = np.random.choice([0,0.3,0.5,0.8,1], 100) df = pd.concat([df, pd.Series(tars, name='group')], axis=1) fig = plt.figure(figsize=(10,8), dpi=300) ax = fig.add_subplot(1,1,1) # 1. 定义颜色映射和数值范围 cmap = cm.viridis norm = Normalize(vmin=df['group'].min(), vmax=df['group'].max()) # 创建ScalarMappable对象,这是色条需要的核心对象 sm = cm.ScalarMappable(norm=norm, cmap=cmap) sm.set_array([]) # 这里需要传入一个空数组,因为我们已经通过norm指定了范围 # 2. 循环绘制散点,用sm.to_rgba获取对应颜色 targets = pd.unique(tars) for target in targets: ax.scatter( df.loc[df.group == target, 'S1'], df.loc[df.group == target, 'S2'], color=sm.to_rgba(target) # 根据target值获取对应颜色 ) # 3. 添加色条,传入我们创建的sm对象 fig.colorbar(sm, ax=ax, label='Group Value') plt.show()
关键说明:
Normalize用来指定数值的最小/最大值,确保色条的范围和你的group变量一致ScalarMappable是连接数值和颜色的桥梁,fig.colorbar()需要这个对象来生成对应的色条- 循环里用
sm.to_rgba(target)来获取每个分组对应的颜色,保证所有散点都遵循同一个颜色映射规则
这样就能得到你想要的连续色条啦~
内容的提问来源于stack exchange,提问作者Sos
相关产品推荐
相关产品推荐

