基于第三变量修改Colorbar特定区域颜色的技术实现问询
解决方案
问题核心
你当前代码直接传递颜色字符串给scatter的c参数,导致Colorbar无法关联深度(De)的数值范围。要实现需求,需要将线下点的深度值和线上点的统一标记值映射到颜色空间,再同步到Colorbar。
修改后代码
import pandas as pd import numpy as np import matplotlib.pyplot as plt from matplotlib.ticker import FormatStrFormatter from matplotlib.colors import LinearSegmentedColormap, Normalize xls = pd.ExcelFile('20240109 - CPeT Export - Rev2.xlsx') God = pd.ExcelFile('20231213-Vs calculations.xlsx') n = len(xls.sheet_names) #------Raw data-------------------------------------------------------------------------------------# dfs = pd.read_excel(xls, sheet_name='SCPTU-12-CPT', skiprows=185, skipfooter=0) title = dfs.values[0,0] qt = dfs.values[:,5] # Cone tip resistance (MPa) ov = dfs.values[:,10] # Vertical total stress (kPa) Qtn = dfs.values[:,18] # Normalised cone tip resistance with stress component (-) De = dfs.values[:,1] # Imports depth values (m) Gor = pd.read_excel(God, sheet_name='SCPTU-12-CPT', skiprows=185, skipfooter=0) Go = Gor.values[:,8] # Imports the correct small-strain shear modulus (MPa) D = Gor.values[:,0] # Imports depth values (m) #------Calculations---------------------------------------------------------------------------------# ov = ov/1000 qn = qt-ov # Calculates qn IG = Go/qn # Calculates normalised rigidty index #------Plotting the results-------------------------------------------------------------------------# fig = plt.figure() y = 2280.4*IG**-1.333 # 1. 构建自定义颜色映射:蓝色渐变(对应线下深度)+ 红色(对应线上点) blue_cmap = plt.get_cmap('Blues') # 提取蓝色渐变的前90%色调,最后添加纯红色 color_list = blue_cmap(np.linspace(0, 0.9, 100)) color_list = np.vstack([color_list, np.array([1, 0, 0, 1])]) custom_cmap = LinearSegmentedColormap.from_list('depth_cmap', color_list) # 2. 构建颜色值数组:线下点用实际深度值,线上点用深度最大值+1作为标记 color_values = np.where(Qtn < y, De, De.max() + 1) # 3. 设置归一化范围,覆盖深度最小值到标记值 norm = Normalize(vmin=De.min(), vmax=De.max() + 1) ax = fig.gca() ax.set_xscale('log') ax.set_yscale('log') ax.yaxis.set_major_formatter(FormatStrFormatter('%g')) ax.xaxis.set_major_formatter(FormatStrFormatter('%g')) plt.xlabel('Normalised Rigidity Index, $I_G$') plt.ylabel('Normalised Cone Tip Resistance, Qtn') # 4. 散点图使用数值化的颜色值、自定义色图和归一化规则 sc = ax.scatter(IG, Qtn, s=60, label=title, c=color_values, cmap=custom_cmap, norm=norm) plt.plot([1,330],[(330/1)**(1/0.75),1], linewidth=1, color="black",linestyle='-', marker='None') # 5. 配置Colorbar:设置刻度并修改最后一个刻度的标签 cbar = plt.colorbar(sc, ticks=[De.min(), De.max(), De.max() + 1]) cbar.ax.set_yticklabels([f'{De.min():.1f} m', f'{De.max():.1f} m', 'Above line']) cbar.ax.invert_yaxis() cbar.set_label('Depth') ax.set_xlim(1, 1000) ax.set_ylim(1, 1000) plt.legend() plt.show()
关键修改说明
- 颜色映射逻辑:放弃直接使用颜色字符串,改用深度数值(线下点)和标记值(线上点)作为颜色输入,让Colorbar能识别数值范围。
- 自定义色图:用蓝色渐变对应深度变化(浅蓝=浅埋,深蓝=深埋),红色专门标记线上的点,匹配预期效果。
- Colorbar配置:通过修改刻度标签,把超出深度范围的标记值替换为"Above line",清晰区分两类点的含义。
内容的提问来源于stack exchange,提问作者Scott
相关产品推荐
相关产品推荐

