Matplotlib双Y轴图表:如何根据data3设置背景颜色?
用Matplotlib根据data3设置图表彩色背景的解决方案
嘿,我来帮你搞定这个彩色背景的问题!其实核心思路就是把data3的数值映射成对应的颜色,然后填充到图表的背景区域里。结合你已经有的双Y轴设置,我给你两种实现方式,分块渐变和连续渐变,你可以按需选择:
方式一:分块彩色背景(对应每个数据点区间)
这种方式会把相邻两个时间点之间的背景用对应data3值的颜色填充,适合数据点间隔清晰的场景:
import matplotlib.pyplot as plt from datetime import datetime as dt import matplotlib.dates as md from matplotlib import cm from matplotlib.colors import Normalize # 替换成你自己的真实数据 dates = [dt(2023, 1, i) for i in range(1, 11)] data1 = [51.2 + i*0.5 for i in range(10)] data2 = [48.3 - i*0.3 for i in range(10)] data3 = [20, 25, 30, 35, 40, 45, 50, 55, 60, 65] fig, ax1 = plt.subplots(constrained_layout=True) # 绘制左侧Y轴的data1和data2 ax1.plot(dates, data1, label='data1', color='blue') ax1.plot(dates, data2, label='data2', color='green') ax1.set_ylabel('data1/data2 Values') ax1.legend(loc='upper left') # 设置右侧Y轴的data3 ax2 = ax1.twinx() ax2.plot(dates, data3, label='data3', color='red') ax2.set_ylabel('data3 Values') ax2.legend(loc='upper right') # 格式化时间轴 ax1.xaxis.set_major_formatter(md.DateFormatter('%Y-%m-%d')) plt.xticks(rotation=45) # 关键:将data3数值映射为颜色 # 先把data3归一化到0-1范围,适配颜色映射 norm = Normalize(vmin=min(data3), vmax=max(data3)) cmap = cm.RdYlBu # 可以换成你喜欢的配色,比如coolwarm、viridis # 遍历每个时间区间,填充背景 for i in range(len(dates)-1): start_date = dates[i] end_date = dates[i+1] # 获取当前data3对应的颜色 bg_color = cmap(norm(data3[i])) # 绘制垂直背景块,alpha控制透明度避免遮挡曲线 ax1.axvspan(start_date, end_date, facecolor=bg_color, alpha=0.3) plt.show()
方式二:连续渐变背景
如果想要更平滑的背景过渡,可以用imshow绘制连续的颜色渐变,适合data3变化平缓的场景:
import matplotlib.pyplot as plt from datetime import datetime as dt import matplotlib.dates as md from matplotlib import cm from matplotlib.colors import Normalize # 替换成你自己的真实数据 dates = [dt(2023, 1, i) for i in range(1, 11)] data1 = [51.2 + i*0.5 for i in range(10)] data2 = [48.3 - i*0.3 for i in range(10)] data3 = [20, 25, 30, 35, 40, 45, 50, 55, 60, 65] fig, ax1 = plt.subplots(constrained_layout=True) # 绘制左侧Y轴的data1和data2 ax1.plot(dates, data1, label='data1', color='blue') ax1.plot(dates, data2, label='data2', color='green') ax1.set_ylabel('data1/data2 Values') ax1.legend(loc='upper left') # 设置右侧Y轴的data3 ax2 = ax1.twinx() ax2.plot(dates, data3, label='data3', color='red') ax2.set_ylabel('data3 Values') ax2.legend(loc='upper right') # 格式化时间轴 ax1.xaxis.set_major_formatter(md.DateFormatter('%Y-%m-%d')) plt.xticks(rotation=45) # 关键:绘制连续渐变背景 # 把时间转换成matplotlib能识别的数值格式 x_num = md.date2num(dates) # 创建覆盖整个图表区域的网格 X, Y = plt.meshgrid(x_num, ax1.get_ylim()) # 将data3扩展成和网格匹配的形状 Z = [[data3[i] for i in range(len(x_num))] for _ in range(len(Y))] # 绘制渐变背景 norm = Normalize(vmin=min(data3), vmax=max(data3)) cmap = cm.RdYlBu im = ax1.imshow(Z, extent=[x_num[0], x_num[-1], ax1.get_ylim()[0], ax1.get_ylim()[1]], origin='lower', cmap=cmap, norm=norm, alpha=0.3, aspect='auto') # 添加颜色条,关联到右侧Y轴 fig.colorbar(im, ax=ax2, label='data3 Value') plt.show()
小提示
- 你可以替换
cmap参数来切换配色方案,Matplotlib内置了超多配色,比如viridis、coolwarm、plasma都是常用的选择。 alpha参数调整背景透明度,数值越小越透明,避免遮挡前景的曲线。- 如果你的
data3是和时间点一一对应的,两种方式都能直接适配,只需要替换成你自己的真实数据即可。
内容的提问来源于stack exchange,提问作者Tobias M.
相关产品推荐
相关产品推荐

