如何控制颜色条次级Y轴的刻度位置与数量
问题描述
我有一个展示概率对数的颜色条,希望添加一组显示原始概率值的次级Y轴刻度。目前已初步实现,但无法控制次级刻度的位置与数量:增加请求的刻度数量后,刻度会集中在颜色条顶部,可读性极差。我需要设置10个刻度,其中:
- 3个对应0.1以上的概率
- 5-7个在0到0.1之间
- 3-5个在0.0001到0.1之间(注:原描述区间存在逻辑冲突,此处按合理逻辑调整)
无需与主刻度对齐。
原实现代码如下:
cbar_label = "Log base 10 of probability" cbar_fontSize = 15 cbar_nBins = 25 cbar = plt.colorbar(mesh1, ax=axs.ravel().tolist()) cbar.ax.set_ylabel(cbar_label, fontsize = cbar_fontSize) cbar.ax.locator_params(nbins=cbar_nBins) cbar_tick_labels_pre = [float(t.get_text().replace('−','-')) for t in cbar.ax.get_yticklabels()] cbar_round = 4 cbar_tick_labels = [round(10**t, cbar_round) for t in cbar_tick_labels_pre] cbar_label_2 = "probability" # 定义两个刻度体系的转换函数 def logP_to_P(x): val = 10**(np.ma.masked_invalid(x)) return np.ma.masked_invalid(val) def P_to_logP(x): val = np.log10(np.ma.masked_invalid(x)) return np.ma.masked_invalid(val) # 创建次级Y轴 cbar2 = cbar.ax.secondary_yaxis('left',functions=(logP_to_P,P_to_logP)) cbar2.set_ylabel(cbar_label_2, fontsize = cbar_fontSize, y=0.87) #cbar_nBins_2 = 15 cbar_nBins_2 = 10 cbar2.locator_params(nbins=cbar_nBins_2)
解决方案
问题核心是概率与对数概率为非线性映射,默认线性刻度定位器会导致刻度集中在高概率区域(对数刻度顶部)。解决方法是手动指定符合需求的概率刻度点,再转换为对数坐标位置。
修改后的代码如下:
import numpy as np import matplotlib.pyplot as plt # 保留原颜色条基础设置 cbar_label = "Log base 10 of probability" cbar_fontSize = 15 cbar_nBins = 25 cbar = plt.colorbar(mesh1, ax=axs.ravel().tolist()) cbar.ax.set_ylabel(cbar_label, fontsize=cbar_fontSize) cbar.ax.locator_params(nbins=cbar_nBins) cbar_label_2 = "probability" # 刻度转换函数 def logP_to_P(x): val = 10**(np.ma.masked_invalid(x)) return np.ma.masked_invalid(val) def P_to_logP(x): val = np.log10(np.ma.masked_invalid(x)) return np.ma.masked_invalid(val) # 创建次级轴 cbar2 = cbar.ax.secondary_yaxis('left', functions=(logP_to_P, P_to_logP)) cbar2.set_ylabel(cbar_label_2, fontsize=cbar_fontSize, y=0.87) # 手动定义概率刻度:按需求分配区间,共10个刻度 # 0.1以上:3个;0.0001-0.1:4个;0-0.0001:3个 p_ticks = [0.2, 0.5, 1.0, 0.01, 0.001, 0.0005, 0.0001, 1e-5, 1e-6, 1e-7] # 将概率值转换为对数坐标,设置为次级轴刻度 logp_ticks = np.log10(p_ticks) cbar2.set_yticks(logp_ticks) # 格式化刻度标签:小概率用科学计数法,大概率用小数,提升可读性 cbar2.set_yticklabels([f"{p:.1e}" if p < 0.01 else f"{p:.2f}" for p in p_ticks])
关键要点
- 手动指定刻度:直接定义符合区间需求的概率值,避开线性定位器的缺陷
- 标签格式化:根据概率大小选择显示格式,避免全部用科学计数法或小数导致的可读性问题
- 非线性适配:通过
np.log10将概率刻度转换为对数坐标,完美匹配主颜色条的刻度位置
内容的提问来源于stack exchange,提问作者blaughli
相关产品推荐
相关产品推荐

