如何从已有的Matplotlib散点图中提取色条?
问题:提取Pickle保存的Matplotlib散点图色条到复合图中
我正在为论文制作复合图,需要加载以pickle格式保存的Matplotlib图形。我用get_offsets()获取散点坐标,get_facecolor()获取点的颜色,代码如下:
加载图形
with open('Figures paper/Individual spectra figures/Spectra_1000_GALL_chunk_0.pickle', 'rb') as fl: ax1 = pickle.load(fl)
获取绘图特征并绘制到新子图
xd = axp.collections[0].get_offsets()[:,0] yd = axp.collections[0].get_offsets()[:,1] cd = axp.collections[0].get_facecolor() ax.scatter(xd,yd, s=ar,c=cd ,alpha=0.8)
我能在新复合图的子面板中绘制这些点,但原图形的色条无法提取到新图中。尝试用提取的散点数据新建色条,却发现get_facecolor()仅返回颜色值,无法获取生成颜色的原始变量,因此无法实现。请问该如何解决?
解决方法
先修正代码笔误
你代码中加载得到的是ax1,但后续用了axp,这大概率是笔误,后续代码请统一用ax1指代加载的轴对象。
方案1:从原散点集合提取色映射参数重建色条
原pickle加载的散点集合(Collection)本身关联了颜色映射(cmap)和归一化(norm)规则,直接提取这些参数即可重建一致的色条:
# 1. 获取原散点的Collection对象 scatter_coll = ax1.collections[0] # 2. 提取颜色映射核心参数 cmap = scatter_coll.get_cmap() norm = scatter_coll.get_norm() vmin, vmax = norm.vmin, norm.vmax # 3. 在新子图绘制散点,并基于提取的参数创建色条 ax.scatter(xd, yd, s=ar, c=cd, alpha=0.8, cmap=cmap, norm=norm) # 方法A:直接用原Collection创建色条 fig.colorbar(scatter_coll, ax=ax) # 方法B:如果方法A报错,手动创建ScalarMappable生成色条 from matplotlib.cm import ScalarMappable sm = ScalarMappable(norm=norm, cmap=cmap) sm.set_array([]) # 无需原始数据,仅用范围生成色条 fig.colorbar(sm, ax=ax)
方案2:直接提取原图形中的色条对象复用
如果原pickle保存的图形已经包含色条,可以直接找到并复用其配置:
import matplotlib # 遍历原图形的所有轴,查找色条对应的轴 for cax in ax1.figure.get_axes(): if isinstance(cax, matplotlib.colorbar.ColorbarAxes): # 提取原色条的映射对象,在新图中创建一致的色条 fig.colorbar(cax.colorbar.mappable, ax=ax) break
方案3:从颜色值反推原始变量(备选)
如果上述方法都失效,可以通过颜色值反推对应的原始变量范围,再生成色条:
# 从颜色值反推对应的归一化数值 norm_values = cmap.inversed(cd) # 用反推的数值创建色条 ax.scatter(xd, yd, s=ar, c=norm_values, alpha=0.8, cmap=cmap, norm=norm) fig.colorbar(ScalarMappable(norm=norm, cmap=cmap), ax=ax)
内容的提问来源于stack exchange,提问作者Paulalo
相关产品推荐
相关产品推荐

