Matplotlib绘图X轴标签重叠,如何修改为仅显示小时刻度?
解决Matplotlib X轴时间标签重叠并自定义小时刻度的问题
我懂你遇到的麻烦——密密麻麻的分钟级时间标签挤在一起根本没法读,想要换成清爽的0h,1h,2h...刻度对吧?咱们可以通过自定义X轴刻度和标签彻底解决这个问题,同时搞定重叠的困扰。
下面是修改后的完整代码,我会逐部分解释关键改动:
import os import matplotlib.pyplot as plt from PyQt5 import QtGui def draw_pic_sukub_single(pic, rows, str_selected_opt): img_name = 'image.jpg' plt.clf() dict_data = rows_to_dict(rows) print(dict_data) # 先收集所有X轴时间数据,方便后续计算刻度范围 all_time_points = [] for key_date in dict_data.keys(): for list_data in dict_data[key_date]: all_time_points.append(list_data[0]) plt.figure() for key_date in dict_data.keys(): x, y = [], [] for list_data in dict_data[key_date]: x.append(list_data[0]) y.append(list_data[dict_opt[str_selected_opt]]) plt.plot(x, y, '-', label=key_date) # --- 核心改动:自定义小时刻度 --- # 1. 把HH:MM:SS字符串转成小时数值(比如'00:00:00'→0,'01:30:00'→1.5) def convert_time_to_hour(time_str): hours, mins, secs = map(int, time_str.split(':')) return hours + mins/60 + secs/3600 # 2. 计算需要显示的小时范围 hour_nums = [convert_time_to_hour(t) for t in all_time_points] start_hour = int(min(hour_nums)) end_hour = int(max(hour_nums)) + 1 # 确保包含最后一个完整小时 # 3. 设置X轴刻度:指定位置(对应整小时的时间点)和显示标签(0h,1h...) plt.xticks( ticks=[convert_time_to_hour(f"{h:02d}:00:00") for h in range(start_hour, end_hour)], labels=[f"{h}h" for h in range(start_hour, end_hour)] ) # 4. 优化标签显示:刻度少了直接水平放,不用旋转也不会重叠 plt.xticks(rotation=0, ha='center') plt.legend() # 别忘了加图例区分不同日期的曲线 plt.savefig(img_name) # 用os.path.join拼接路径更安全,适配不同系统 pic.setPixmap(QtGui.QPixmap(os.path.join(os.getcwd(), img_name))) return pic
关键改动说明:
- 收集全量时间数据:先拿到所有X轴的时间点,能精准计算出需要覆盖的小时范围(比如从0h到9h),避免刻度漏显示或多余显示。
- 时间转小时数值:把
HH:MM:SS格式的字符串转换成小时数,让Matplotlib能准确找到刻度的位置。 - 手动指定刻度:直接定义要显示的刻度位置(对应整小时的时间点)和标签文本(
0h这种简洁格式),完全替换掉原来密集的分钟刻度。 - 优化路径拼接:用
os.path.join代替手动拼路径,避免Windows和Linux系统的路径分隔符问题。 - 调整标签角度:现在刻度数量大幅减少,直接水平显示更清爽,不用再旋转35度。
如果你的数据跨了多天(比如从23:00到次日02:00),可以稍微修改convert_time_to_hour函数,把日期因素也加进去,不过从你的问题描述看,单日小时数据的场景下这个方案完全够用。
内容的提问来源于stack exchange,提问作者leggod1004
相关产品推荐
相关产品推荐

