Matplotlib绘制归一化数组时线条颜色与数组值不匹配问题
问题:Matplotlib线条颜色与数组值不匹配
我尝试用Matplotlib通过线条展示数组Pe,但输出里的线条颜色和数组实际值不匹配。比如标记为0的线条对应数值394.20560747663563,按颜色映射应该显示蓝色,实际却是黄色。
相关代码
import matplotlib as mpl import matplotlib.pyplot as plt from matplotlib.patches import Rectangle import numpy as np from matplotlib.colors import Normalize from matplotlib import cm import math from numpy import nan fig,aPe = plt.subplots(1) n=3 N=2*n*(n-1) J = np.array([[]]) Pe=np.array([[394.20560747663563, 408.7929050665396 , 419.132709901089 , 398.95097406721044, 403.81198021076113, 430.00914784982064, 424.50127213826016, 453.54817733128607, 441.4651085668709 , 447.42507960635163, 413.8982415602072 , 390.3025816600353 ]]) C1 = nan for i in J[0]: Pe = np.insert(Pe, i, [C1], axis=1) print("Pe =", [Pe]) for i in range(0,len(Pe)): Max=max(max(Pe[i]), max(Pe[i])) Min=min(min(Pe[i]), min(Pe[i])) a=Min b=Max Amax= math.ceil(Max) Amin= math.floor(Min) print(Amax, Amin) color = cm.get_cmap('Dark2') norm = Normalize(vmin=Amin, vmax=Amax) color_list = [] for i in range(len(Pe[0])): color_list.append(color(Pe[0,i]/Amax)) id = 0 for j in range(0, n): for k in range(n-1): aPe.hlines(200+200*(n-j-1)+5*n, 200*(k+1)+5*n, 200*(k+2)+5*n, zorder=0, colors=color_list[id]) id += 1 for i in range(0, n): rect = mpl.patches.Rectangle((200+200*i, 200+200*j), 10*n, 10*n, linewidth=1, edgecolor='black', facecolor='black') aPe.add_patch(rect) if j < n-1: aPe.vlines(200+200*i+5*n, 200*(n-1-j)+5*n, 200*(n-j)+5*n, zorder=0, colors=color_list[id]) id += 1 cb = fig.colorbar(cm.ScalarMappable(cmap=color, norm=norm)) cb.set_label("Entry pressure (N/m$^{2}$)") aPe.set_xlim(left = 0, right = 220*n) aPe.set_ylim(bottom = 0, top = 220*n) plt.axis('off') plt.show()
问题原因
颜色映射的计算逻辑错误:当前代码用Pe[0,i]/Amax直接作为颜色映射的输入,但cm.get_cmap()的输入需要是归一化后的值(范围0到1),而不是原始值除以最大值。正确的做法是用之前定义的norm对象对Pe的数值做归一化处理,这样才能和色条的映射规则保持一致。
修复方案
修改生成color_list的循环部分,用norm对每个数值做归一化后再传入颜色映射:
color_list = [] for val in Pe[0]: color_list.append(color(norm(val)))
修改后的完整代码
import matplotlib as mpl import matplotlib.pyplot as plt from matplotlib.patches import Rectangle import numpy as np from matplotlib.colors import Normalize from matplotlib import cm import math from numpy import nan fig,aPe = plt.subplots(1) n=3 N=2*n*(n-1) J = np.array([[]]) Pe=np.array([[394.20560747663563, 408.7929050665396 , 419.132709901089 , 398.95097406721044, 403.81198021076113, 430.00914784982064, 424.50127213826016, 453.54817733128607, 441.4651085668709 , 447.42507960635163, 413.8982415602072 , 390.3025816600353 ]]) C1 = nan for i in J[0]: Pe = np.insert(Pe, i, [C1], axis=1) print("Pe =", [Pe]) for i in range(0,len(Pe)): Max=max(max(Pe[i]), max(Pe[i])) Min=min(min(Pe[i]), min(Pe[i])) a=Min b=Max Amax= math.ceil(Max) Amin= math.floor(Min) print(Amax, Amin) color = cm.get_cmap('Dark2') norm = Normalize(vmin=Amin, vmax=Amax) color_list = [] # 修复颜色映射逻辑 for val in Pe[0]: color_list.append(color(norm(val))) id = 0 for j in range(0, n): for k in range(n-1): aPe.hlines(200+200*(n-j-1)+5*n, 200*(k+1)+5*n, 200*(k+2)+5*n, zorder=0, colors=color_list[id]) id += 1 for i in range(0, n): rect = mpl.patches.Rectangle((200+200*i, 200+200*j), 10*n, 10*n, linewidth=1, edgecolor='black', facecolor='black') aPe.add_patch(rect) if j < n-1: aPe.vlines(200+200*i+5*n, 200*(n-1-j)+5*n, 200*(n-j)+5*n, zorder=0, colors=color_list[id]) id += 1 cb = fig.colorbar(cm.ScalarMappable(cmap=color, norm=norm)) cb.set_label("Entry pressure (N/m$^{2}$)") aPe.set_xlim(left = 0, right = 220*n) aPe.set_ylim(bottom = 0, top = 220*n) plt.axis('off') plt.show()
修改后,线条颜色会正确对应Pe数组的数值,比如394.20的低值会映射到Dark2色图的蓝色区域,高值对应更深的颜色,和右侧色条的映射规则完全一致。
内容的提问来源于stack exchange,提问作者user19862793
相关产品推荐
相关产品推荐

