Matplotlib周程网格文本对齐、网格线及轴间距调整技术咨询
周学习日程可视化问题及修复方案
现有代码
import json import sys import matplotlib.pyplot as plt import numpy as np if len(sys.argv) != 2: print("Usage: python script_name.py <path_to_input_json>") sys.exit(1) filename = sys.argv[1] with open(filename) as f: data = json.load(f) # Set up figure and axes fig, ax = plt.subplots(figsize=(12, 10)) # Set up data for grid periods = ['early_morning', 'morning', 'noon', 'afternoon', 'evening', 'night', 'late_night'] days = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'] grid_data = np.full((len(periods), len(days)), '', dtype=object) # Set up axes ax.set_xticks(np.arange(len(days))) ax.set_yticks(np.arange(len(periods))) ax.set_xticklabels(days) ax.set_yticklabels(periods) ax.set_title('Weekly Schedule') ax.set_xlabel('Day of the week') ax.set_ylabel('Time Periods') # Rotate x-axis labels to prevent overlap plt.setp(ax.get_xticklabels(), rotation=45, ha="right", rotation_mode="anchor") # Adjust spacing to prevent label overlap fig.tight_layout() # Populate grid for i, day in enumerate(days): for j, period in enumerate(periods): cell_text = [] if day in data and period in data[day]: if data[day][period]['accuracy_level'] >= 0.7: for item in data[day][period]['study_material']: if item['accuracy_level'] >= 0.7: cell_text.append(item['course']) cell_text.append(item['subject']) if data[day][period]['accuracy_level'] >= 0.7: cell_text.append(data[day][period]['platform_group']) if cell_text: ax.text(j, i, cell_text, ha='center', va='center') # Save figure plt.savefig('weekly_schedule.png')
当前可视化问题
当前生成的周学习日程图存在文本未对齐到网格单元格、无网格线等问题,现咨询以下技术问题:
- 如何基于输入数据中的periods和days值,将文本精准对齐到网格的对应单元格位置?
- 是否可以在该可视化图形中绘制网格线?
- 是否可以分别调整Y轴上'early_morning'与'late_night'、X轴上'Monday'与'Sunday'的间距?
解决方案
1. 文本精准对齐到网格单元格
原代码中ax.text(j, i, cell_text...)的坐标顺序错误,Matplotlib中ax.text的参数是(x, y),而你循环时i是days的索引(对应X轴),j是periods的索引(对应Y轴),需交换两者位置。同时,cell_text是列表,直接传入会打印成列表格式,需用'\n'.join(cell_text)转成换行文本,方便在单元格内显示。
修改后的填充网格代码:
# Populate grid for i, day in enumerate(days): for j, period in enumerate(periods): cell_text = [] if day in data and period in data[day]: if data[day][period]['accuracy_level'] >= 0.7: for item in data[day][period]['study_material']: if item['accuracy_level'] >= 0.7: cell_text.append(item['course']) cell_text.append(item['subject']) if data[day][period]['accuracy_level'] >= 0.7: cell_text.append(data[day][period]['platform_group']) # 去重避免重复添加platform_group cell_text = list(dict.fromkeys(cell_text)) if cell_text: ax.text(i, j, '\n'.join(cell_text), ha='center', va='center', fontsize=10)
2. 添加网格线
可以通过ax.grid()添加网格线,并设置样式、透明度等属性,同时确保网格线在文本下方:
# 添加网格线 ax.grid(True, linestyle='-', color='gray', alpha=0.7) # 确保网格线在文本下方 ax.set_axisbelow(True)
将这段代码放在设置坐标轴的代码块之后即可。
3. 调整特定轴标签的间距
Matplotlib默认轴刻度均匀分布,要单独调整首尾标签间距,需自定义刻度位置:
X轴(周一和周日间距调整)
# 自定义X轴刻度位置,放大周一和周日的外侧间距 x_ticks = np.arange(len(days)) x_ticks[0] -= 0.2 # 周一左移 x_ticks[-1] += 0.2 # 周日右移 ax.set_xticks(x_ticks) ax.set_xticklabels(days)
Y轴(early_morning和late_night间距调整)
# 自定义Y轴刻度位置,放大首尾时段的外侧间距 y_ticks = np.arange(len(periods)) y_ticks[0] -= 0.2 # early_morning上移 y_ticks[-1] += 0.2 # late_night下移 ax.set_yticks(y_ticks) ax.set_yticklabels(periods)
内容的提问来源于stack exchange,提问作者David Faizulaev
相关产品推荐
相关产品推荐

