使用adjustText优化分类Y轴图表标签间距的问题求助
问题
使用adjustText为分类Y轴图表的每条水平线添加对应列标签时,底部最后一条线的标签与线条距离过近,无法像顶部线条那样保持合理间距,尝试adjustText多数参数仍未解决。
原数据集代码
import pandas as pd import matplotlib.pyplot as plt from adjustText import adjust_text df = pd.DataFrame([['Trip: 450121805 - Batched_with: 450115425', '2024-01-17 12:22:52.000', '2024-01-17 12:27:51.000', '2024-01-17 12:47:14.000', '2024-01-17 12:47:46.000', '2024-01-17 12:47:14.000', '2024-01-17 12:59:26.000', '2024-01-17 12:59:26.000'], ['Trip: 450115425 - Batched_with: 450121805', '2024-01-17 11:57:32.000', '2024-01-17 12:02:31.000', '2024-01-17 12:14:53.000', '2024-01-17 12:15:25.000', '2024-01-17 12:47:14.000', '2024-01-17 12:48:54.000', '2024-01-17 12:59:26.000'], ['Trip: 450115515 - Batched_with: 450121805', '2024-01-17 11:57:58.000', '2024-01-17 12:02:58.000', '2024-01-17 12:15:10.000', '2024-01-17 12:15:41.000', '2024-01-17 12:47:14.000', '2024-01-17 12:49:06.000', '2024-01-17 12:59:26.000'], ['Trip: 450121805 - Batched_with: 450118017', '2024-01-17 12:22:52.000', '2024-01-17 12:27:51.000', '2024-01-17 12:47:14.000', '2024-01-17 12:47:46.000', '2024-01-17 12:47:15.000', '2024-01-17 12:59:26.000', '2024-01-17 12:59:26.000'], ['Trip: 450118017 - Batched_with: 450121805', '2024-01-17 12:08:52.000', '2024-01-17 12:13:51.000', '2024-01-17 12:28:09.000', '2024-01-17 12:28:52.000', '2024-01-17 12:47:15.000', '2024-01-17 12:52:29.000', '2024-01-17 12:59:26.000'], ['Trip: 450119629 - Batched_with: 450121805', '2024-01-17 12:15:07.000', '2024-01-17 12:20:07.000', '2024-01-17 12:38:06.000', '2024-01-17 12:38:26.000', '2024-01-17 12:47:15.000', '2024-01-17 12:55:45.000', '2024-01-17 12:59:26.000']]) df.set_index(0, inplace=True) df.columns = ['created_in_time_1', 'created_in_time_2', 'created_in_time_3', 'created_in_time_4', 'created_in_time_5', 'created_in_time_6', 'created_in_time_7']
原绘图代码
times_ = ['created_in_time_1', 'created_in_time_2', 'created_in_time_3', 'created_in_time_4', 'created_in_time_5', 'created_in_time_6', 'created_in_time_7'] fig, ax = plt.subplots(figsize=(30, 15), sharex = True, sharey = True) for t in times_: df[t] = pd.to_datetime(df[t]) for i, row in df.iterrows(): ax.plot([row['created_in_time_1'], row['created_in_time_2'], row['created_in_time_3'], row['created_in_time_4'], row['created_in_time_5'], row['created_in_time_6'], row['created_in_time_7']], [i, i, i, i, i, i, i], '-X', label=i, linewidth=2.0) texts = [ax.text(row[j], i, '%s' %times_[n], ha='center', va='center') for n, j in enumerate(times_)] adjust_text(texts, expand=(5, 5), arrowprops=dict(arrowstyle='->', color='red'))
解决方案
问题核心是每行单独调用adjustText无法全局优化布局,且底部行文本没有足够向下扩展空间。以下是修复后的完整代码:
import pandas as pd import matplotlib.pyplot as plt from adjustText import adjust_text # 数据集部分 df = pd.DataFrame([['Trip: 450121805 - Batched_with: 450115425', '2024-01-17 12:22:52.000', '2024-01-17 12:27:51.000', '2024-01-17 12:47:14.000', '2024-01-17 12:47:46.000', '2024-01-17 12:47:14.000', '2024-01-17 12:59:26.000', '2024-01-17 12:59:26.000'], ['Trip: 450115425 - Batched_with: 450121805', '2024-01-17 11:57:32.000', '2024-01-17 12:02:31.000', '2024-01-17 12:14:53.000', '2024-01-17 12:15:25.000', '2024-01-17 12:47:14.000', '2024-01-17 12:48:54.000', '2024-01-17 12:59:26.000'], ['Trip: 450115515 - Batched_with: 450121805', '2024-01-17 11:57:58.000', '2024-01-17 12:02:58.000', '2024-01-17 12:15:10.000', '2024-01-17 12:15:41.000', '2024-01-17 12:47:14.000', '2024-01-17 12:49:06.000', '2024-01-17 12:59:26.000'], ['Trip: 450121805 - Batched_with: 450118017', '2024-01-17 12:22:52.000', '2024-01-17 12:27:51.000', '2024-01-17 12:47:14.000', '2024-01-17 12:47:46.000', '2024-01-17 12:47:15.000', '2024-01-17 12:59:26.000', '2024-01-17 12:59:26.000'], ['Trip: 450118017 - Batched_with: 450121805', '2024-01-17 12:08:52.000', '2024-01-17 12:13:51.000', '2024-01-17 12:28:09.000', '2024-01-17 12:28:52.000', '2024-01-17 12:47:15.000', '2024-01-17 12:52:29.000', '2024-01-17 12:59:26.000'], ['Trip: 450119629 - Batched_with: 450121805', '2024-01-17 12:15:07.000', '2024-01-17 12:20:07.000', '2024-01-17 12:38:06.000', '2024-01-17 12:38:26.000', '2024-01-17 12:47:15.000', '2024-01-17 12:55:45.000', '2024-01-17 12:59:26.000']]) df.set_index(0, inplace=True) df.columns = ['created_in_time_1', 'created_in_time_2', 'created_in_time_3', 'created_in_time_4', 'created_in_time_5', 'created_in_time_6', 'created_in_time_7'] # 绘图部分 times_ = ['created_in_time_1', 'created_in_time_2', 'created_in_time_3', 'created_in_time_4', 'created_in_time_5', 'created_in_time_6', 'created_in_time_7'] fig, ax = plt.subplots(figsize=(30, 15), sharex=True, sharey=True) # 转换时间格式 for t in times_: df[t] = pd.to_datetime(df[t]) # 全局收集所有文本对象 all_texts = [] for i, row in df.iterrows(): # 绘制水平线 ax.plot([row['created_in_time_1'], row['created_in_time_2'], row['created_in_time_3'], row['created_in_time_4'], row['created_in_time_5'], row['created_in_time_6'], row['created_in_time_7']], [i, i, i, i, i, i, i], '-X', label=i, linewidth=2.0) # 添加文本时设置初始偏移,避免和线条重叠 for n, j in enumerate(times_): text = ax.text(row[j], i, f'{times_[n]}', ha='center', va='bottom') all_texts.append(text) # 统一调整所有文本,全局优化布局 adjust_text(all_texts, expand=(1.5, 3), # 增加垂直方向扩展空间 autoalign='y', # 自动垂直对齐 only_move={'points':'y', 'text':'y'}, # 仅允许垂直方向移动 arrowprops=dict(arrowstyle='->', color='red')) plt.tight_layout() plt.show()
关键修改点
- 全局收集文本:将所有文本对象存入
all_texts列表,最后统一调用adjust_text,让算法全局优化布局 - 初始偏移设置:文本初始设置
va='bottom',默认在线条上方,避免初始重叠 - 参数调整:
expand参数增加垂直方向比例,给底部文本足够调整空间only_move限制文本仅垂直移动,避免干扰时间轴可读性autoalign='y'让文本自动在垂直方向对齐,保持布局整洁
内容的提问来源于stack exchange,提问作者aligh
相关产品推荐
相关产品推荐

