如何消除Matplotlib绘制股票时序图时的周末空白?
解决Matplotlib绘制股票日线图时周末/节假日空白问题
方案一:用数值索引映射日期标签(彻底消除空白)
直接放弃Matplotlib的自动时间轴补全,用普通数值索引绘图,再手动把X轴标签替换成交易日日期:
import yfinance as yf import matplotlib.pyplot as plt # 下载股票数据 data = yf.download("AAPL", start="2024-01-01", end="2024-06-01") # 计算累积成交量 data['Cum_Volume'] = data['Volume'].cumsum() fig, ax1 = plt.subplots(figsize=(12,6)) # 用数据行数作为X轴索引,避免自动补全非交易日 ax1.bar(range(len(data)), data['Cum_Volume'], color='steelblue') # 设置X轴标签,每隔10个交易日显示一个,避免重叠 ax1.set_xticks(range(0, len(data), 10)) ax1.set_xticklabels(data.index.strftime('%Y-%m-%d')[::10], rotation=45) # 右侧Y轴绘制收盘价示例 ax2 = ax1.twinx() ax2.plot(range(len(data)), data['Close'], color='crimson') plt.tight_layout() plt.show()
这种方式完全按现有数据点绘制,不会出现任何空白,只是X轴视觉上的间隔对应交易日,不是严格的时间等距。
方案二:用日期数值转换配合手动定位时间轴
把日期转为Matplotlib可识别的数值,再设置只显示工作日标签,避免自动补全非交易日:
import yfinance as yf import matplotlib.pyplot as plt import matplotlib.dates as mdates data = yf.download("AAPL", start="2024-01-01", end="2024-06-01") data['Cum_Volume'] = data['Volume'].cumsum() fig, ax1 = plt.subplots(figsize=(12,6)) # 将日期转为Matplotlib数值格式,按真实日期位置绘制柱状图 ax1.bar(mdates.date2num(data.index), data['Cum_Volume'], color='steelblue', width=0.8) # 设置日期显示格式,只显示每周一的标签 ax1.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d')) ax1.xaxis.set_major_locator(mdates.WeekdayLocator(byweekday=mdates.MONDAY)) plt.xticks(rotation=45) # 右侧Y轴示例 ax2 = ax1.twinx() ax2.plot(data.index, data['Close'], color='crimson') plt.tight_layout() plt.show()
这种方式保留了时间轴的特性,同时不会填充非交易日的空白,柱状图宽度需要根据日期间隔手动调整。
方案三:直接用Pandas内置绘图(最省心)
Pandas的绘图函数会自动识别DatetimeIndex,只绘制存在的数据点,不用自己折腾时间轴:
import yfinance as yf import matplotlib.pyplot as plt data = yf.download("AAPL", start="2024-01-01", end="2024-06-01") data['Cum_Volume'] = data['Volume'].cumsum() fig, ax1 = plt.subplots(figsize=(12,6)) # Pandas柱状图自动适配离散交易日 data['Cum_Volume'].plot(kind='bar', ax=ax1, color='steelblue') # 右侧Y轴绘制收盘价 ax2 = ax1.twinx() data['Close'].plot(ax=ax2, color='crimson') # 调整X轴标签显示间隔,避免重叠 ax1.set_xticks(range(0, len(data), 10)) ax1.set_xticklabels(data.index.strftime('%Y-%m-%d')[::10], rotation=45) plt.tight_layout() plt.show()
代码简洁,自动处理日期逻辑,唯一需要注意的是交易日太多时调整标签间隔。
内容的提问来源于stack exchange,提问作者AndysPythonStuff
相关产品推荐
相关产品推荐

