如何修改Matplotlib渐变面积图:让颜色随收盘价高低变化
调整股票渐变面积图的颜色映射逻辑
需求说明
现有Python脚本绘制埃克森美孚(XOM)与沃尔玛(WMT)的渐变面积图,当前渐变效果为从左到右过渡,需修改为收盘价最高处颜色最深,区域底部(y_offset位置)颜色最浅。
修改后的完整代码
import numpy as np import matplotlib.pyplot as plt from matplotlib.path import Path from matplotlib.patches import PathPatch import pandas as pd def create_area_plot(xx, yy, gradient_cmap, filename, title, y_offset, dates): fig, ax = plt.subplots() # 创建闭合路径用于裁剪渐变区域 path_data = np.column_stack((xx, yy)) path_data = np.vstack([path_data, [xx[-1], y_offset], [xx[0], y_offset]]) path = Path(path_data) patch = PathPatch(path, facecolor='none') ax.add_patch(patch) # 基于收盘价相对高度计算颜色值:最高收盘价对应最深色(值为1),y_offset对应最浅色(值为0) price_range = max(yy) - y_offset color_values = (yy - y_offset) / price_range color_values = np.clip(color_values, 0, 1) # 确保值在0-1区间内 # 逐段绘制渐变填充区域 for i in range(len(xx) - 1): # 获取区间左右端点的颜色 left_color = gradient_cmap(color_values[i]) right_color = gradient_cmap(color_values[i+1]) # 生成渐变图像并裁剪到路径内 im = ax.imshow( [[left_color, right_color]], extent=[xx[i], xx[i+1], y_offset, max(yy[i], yy[i+1])], aspect='auto', zorder=0 ) im.set_clip_path(patch) # 图表样式自定义 ax.set_xlabel('Date') ax.set_ylabel('Close') ax.set_title(title) # 设置X轴日期标签,避免截断 ax.set_xticks(xx[::len(xx)//10]) ax.set_xticklabels( [x.strftime('%m/%d/%Y') for x in pd.to_datetime(dates[::len(xx)//10])], rotation=45, ha="right" ) plt.tight_layout() plt.savefig(filename) plt.show() plt.close() # 读取并预处理数据 xom_data = pd.read_csv('http://salilgangal.com/info/XOM.csv') wmt_data = pd.read_csv('http://salilgangal.com/info/WMT.csv') xom_data['Date'] = pd.to_datetime(xom_data['Date']) wmt_data['Date'] = pd.to_datetime(wmt_data['Date']) xom_dates = xom_data['Date'].dt.strftime('%Y-%m-%d') wmt_dates = wmt_data['Date'].dt.strftime('%Y-%m-%d') xom_close_prices = xom_data['Close'] wmt_close_prices = wmt_data['Close'] xx = np.arange(0, xom_dates.size, 1) yy_xom = xom_close_prices.values yy_wmt = wmt_close_prices.values # 计算y_offset:比最低收盘价低5% y_offset_xom = min(yy_xom) - 0.05 * (max(yy_xom) - min(yy_xom)) y_offset_wmt = min(yy_wmt) - 0.05 * (max(yy_wmt) - min(yy_wmt)) # 生成图表 create_area_plot(xx, yy_xom, plt.cm.Blues, "xom_area_chart.png", "XOM Stock Prices", y_offset_xom, xom_dates) create_area_plot(xx, yy_wmt, plt.cm.Reds, "wmt_area_chart.png", "WMT Stock Prices", y_offset_wmt, wmt_dates)
核心修改说明
- 颜色映射逻辑重构:替换原有的从左到右线性渐变,改为基于收盘价相对高度计算颜色值,公式
(收盘价 - y_offset) / (最高收盘价 - y_offset)直接将价格高度映射到0-1的颜色区间,实现“价高色深”的需求。 - 渐变填充方式优化:使用
imshow生成小范围渐变,配合clip_path裁剪出符合数据路径的区域,解决原fill_between无法实现区间内颜色过渡的问题。 - 修复X轴标签bug:将日期数据作为参数传入绘图函数,避免WMT图表错误使用XOM的日期标签。
- 布局优化:添加
plt.tight_layout()防止日期标签被图表边缘截断。
内容的提问来源于stack exchange,提问作者Salil Gangal
相关产品推荐
相关产品推荐

