Python中如何将等高线图颜色映射至mass参数而非等高线层级?
给等高线按mass值配色的解决方案
嘿,我完全懂你的需求——所有数据集的等高线都固定在level=20,但每条线的颜色要对应各自的mass值,而不是跟着Z值的colormap走。咱们可以通过以下几步修改代码来实现:
核心思路
先把所有数据集的mass值收集起来,创建一个颜色映射的尺度,把mass值和colormap的颜色一一对应,然后在循环绘制每条等高线的时候,给它分配对应的颜色就行。
修改后的完整代码
import numpy as np import pylab as plt from pandas import DataFrame as df import matplotlib.colors as colors import scipy.interpolate as interpolate # 假设data已经从文件导入并处理完成 xi = np.linspace(1,10,1000) yi = np.linspace(-1,1,1000) X, Y = np.meshgrid(xi,yi) # 第一步:收集所有mass值,创建颜色归一化规则和colormap masses = [int(data[i]['mass'][0]) for i in range(9)] # 把mass值缩放到0-1范围,适配colormap的索引 norm = colors.Normalize(vmin=np.min(masses), vmax=np.max(masses)) # 选你喜欢的colormap,比如viridis、plasma、coolwarm都可以 cmap = plt.get_cmap('viridis') for i in range(9): Z = interpolate.griddata((data[i]['q'], np.cos(data[i]['iota'])), data[i]['snr1'], (X,Y)) cs = plt.contour(X,Y,Z,levels=[20]) # 获取当前mass对应的颜色 current_mass = masses[i] line_color = cmap(norm(current_mass)) # 给这条等高线设置颜色 cs.collections[0].set_color(line_color) cs.collections[0].set_label(str(current_mass)) # 关键:添加颜色条,让读者清楚mass和颜色的对应关系 sm = plt.cm.ScalarMappable(norm=norm, cmap=cmap) sm.set_array([]) # 因为我们不是用它映射Z值,所以传空数组就行 plt.colorbar(sm, label='mass') plt.legend(loc=5, title='mass') plt.show()
关键改动点解释
- 提前处理mass值:先把所有mass值提取出来,用
Normalize把它们缩放到0到1的范围,这样就能完美匹配colormap的颜色索引了。 - 动态分配颜色:每次循环里,根据当前数据集的mass值,从colormap里取出对应的RGBA颜色,用
set_color()应用到等高线上。 - 添加颜色条:这一步很重要,不然看图的人不知道颜色对应的mass值是多少,用
ScalarMappable可以快速生成和我们的mass映射匹配的颜色条。 - 自定义colormap:你可以把
plt.get_cmap('viridis')里的viridis换成任何你喜欢的colormap名称,比如plasma、coolwarm或者jet,选最适合你数据的配色就行。
这样改完之后,所有level=20的等高线就会根据各自的mass值呈现colormap里的对应颜色,完全满足你的需求啦!
内容的提问来源于stack exchange,提问作者Divyajyoti
相关产品推荐
相关产品推荐

