Python matplotlib中tricontourf对数色条色阶数量不足如何解决?
原因说明
你遇到的问题根源是:tricontourf结合对数归一化/对数Locator时,默认的级别生成逻辑仅会匹配10的整数次幂作为分界点,所以即便你指定了levels=10,最终实际生成的色阶数量仍然只和你数据覆盖的数量级数量一致,导致同数量级内的数值全部对应同一种颜色。
可行解决方案
两种实现方式,按需选择即可:
- 方案1:手动生成对数间隔的色阶(最可控,推荐)
直接根据你的数据范围生成指定数量的对数间隔级别,传入tricontourf的levels参数即可,你想要多少级的色阶直接调整生成级别时的数量参数就行。
修改后的核心代码如下:
else: # 手动生成50个对数间隔的色阶,可按需调整数量 vmin = data.min() vmax = data.max() log_levels = np.logspace(np.log10(vmin), np.log10(vmax), 50) plot = ax[idx].tricontourf(x_coords,y_coords,data, levels=log_levels, norm=matplotlib.colors.LogNorm(), cmap='plasma')
- 方案2:修改
LogLocator参数增加子级别
如果要保留Locator的自动计算逻辑,可以给LogLocator传入subs参数,指定每个数量级内的子间隔乘数,即可在每个数量级内生成多个分级:
plot = ax[idx].tricontourf(x_coords,y_coords,data, 10, locator=matplotlib.ticker.LogLocator(subs=np.arange(1, 10)), cmap='plasma')
这里subs=np.arange(1,10)表示每个10^n ~10^(n+1)的区间内,按1、2、3...9的乘数生成子级别,大幅增加色阶数量。
完整可运行修改版代码
import sys import numpy as np import matplotlib.pyplot as plt import matplotlib from mpl_toolkits.axes_grid1 import make_axes_locatable import math x_coords = np.random.rand((1000)) y_coords = np.random.rand((1000)) values = np.random.rand((1000))*1000 aspect_ratio = (max(x_coords) - min(x_coords)) / (max(y_coords) - min(y_coords)) plots_x = 1 if aspect_ratio > 1.5 else 2 plots_y = 2 if aspect_ratio > 1.5 else 1 fig, ax = plt.subplots(plots_y, plots_x) def plot_field(idx, data, min=1, max=1, log_norm=False): # 确保数据中无0和负值 if log_norm: data = np.clip(data, np.max(data) / 1000000, np.max(data)) if not log_norm: plot = ax[idx].tricontourf(x_coords,y_coords,data, 10, cmap='plasma') else: # 手动生成50级对数色阶,可按需调整数量 vmin = data.min() vmax = data.max() log_levels = np.logspace(np.log10(vmin), np.log10(vmax), 50) plot = ax[idx].tricontourf(x_coords,y_coords,data, levels=log_levels, norm=matplotlib.colors.LogNorm(), cmap='plasma') # ax[idx].scatter(x_coords,y_coords, c='red', s=1) ax[idx].set_aspect(1) divider = make_axes_locatable(ax[idx]) cax = divider.append_axes("right", size="5%", pad=0.05) fig.colorbar(plot,cax=cax) plot_field(0,values, log_norm=True) plt.tight_layout() plt.show()
内容的提问来源于stack exchange,提问作者Finn Eggers
相关产品推荐
相关产品推荐

