Python Matplotlib如何设置多行不同旋转方向的X轴刻度标签?
实现Matplotlib特殊X轴多行列刻度布局
方案一:子图分层实现独立刻度控制
通过创建多个子图分别承载不同行的刻度,实现旋转角度的独立控制:
- 主图负责绘制数据,隐藏自身X轴刻度
- 子图1放置时间刻度,设置垂直旋转
- 子图2放置星期+日期标签,保持水平显示
import matplotlib.pyplot as plt import numpy as np from datetime import datetime # 模拟数据 dates = [datetime(2024, 5, 1, h) for h in range(9, 18)] + [datetime(2024, 5, 2, h) for h in range(9, 18)] times = [d.strftime('%I:%M %p') for d in dates] days = [d.strftime('%A') for d in dates] date_strs = [d.strftime('%d %b %y') for d in dates] values = np.random.rand(len(dates)) # 创建画布与分层子图 fig, (ax_day, ax_time, ax_main) = plt.subplots(3, 1, figsize=(12, 6), gridspec_kw={'height_ratios': [0.5, 0.5, 8]}) # 主图绘制数据并隐藏默认X轴刻度 ax_main.plot(dates, values) ax_main.set_xticks([]) # 时间刻度子图:垂直旋转标签 ax_time.set_xticks(dates) ax_time.set_xticklabels(times, rotation=90, ha='center') ax_time.tick_params(axis='x', length=0) # 隐藏刻度线 ax_time.set_yticks([]) # 隐藏Y轴元素 # 星期+日期子图:仅每日首个刻度显示内容 day_labels = [] for d, day, date in zip(dates, days, date_strs): day_labels.append(f'{day}\n{date}' if d.hour == 9 else '') ax_day.set_xticks(dates) ax_day.set_xticklabels(day_labels, ha='center') ax_day.tick_params(axis='x', length=0) ax_day.set_yticks([]) # 对齐所有子图的X轴范围 ax_day.set_xlim(ax_main.get_xlim()) ax_time.set_xlim(ax_main.get_xlim()) plt.tight_layout() plt.show()
方案二:自定义刻度文本艺术家(Artist)
直接在轴上添加独立的Text对象,精准控制每个标签的旋转角度与位置:
- 获取主图X轴刻度位置,隐藏默认刻度
- 分别添加垂直旋转的时间标签、水平显示的星期日期标签
import matplotlib.pyplot as plt import numpy as np from datetime import datetime # 模拟数据 dates = [datetime(2024, 5, 1, h) for h in range(9, 18)] + [datetime(2024, 5, 2, h) for h in range(9, 18)] times = [d.strftime('%I:%M %p') for d in dates] days = [d.strftime('%A') for d in dates] date_strs = [d.strftime('%d %b %y') for d in dates] values = np.random.rand(len(dates)) fig, ax = plt.subplots(figsize=(12, 6)) ax.plot(dates, values) # 获取刻度位置并隐藏默认刻度 xticks = ax.get_xticks() ax.set_xticks([]) # 添加垂直旋转的时间标签 for x, time in zip(xticks, times): ax.text(x, ax.get_ylim()[0] - 0.1, time, rotation=90, ha='center', va='top', transform=ax.get_xaxis_transform()) # 添加水平显示的星期+日期标签 for x, d, day, date in zip(xticks, dates, days, date_strs): if d.hour == 9: ax.text(x, ax.get_ylim()[0] - 0.25, f'{day}\n{date}', ha='center', va='top', transform=ax.get_xaxis_transform()) plt.subplots_adjust(bottom=0.2) plt.show()
内容的提问来源于stack exchange,提问作者Rowan Hayes
相关产品推荐
相关产品推荐

