Python Tkinter绘制列车运行图:跨零点时间显示问题求助
Python Tkinter 列车运行轨迹图解决方案
针对列车B跨小时时间点导致线段穿越的问题,核心解决思路是将时间统一转换为总秒数,并对跨小时的时间进行补正(加3600秒),确保时间序列始终递增,避免绘图时出现反向线段。以下是完整实现代码:
import tkinter as tk def time_to_seconds(time_str): # 将":MM:SS"格式的时间转换为总秒数 _, mm, ss = time_str.split(':') return int(mm)*60 + int(ss) def process_time_series(times): # 处理时间序列,补正跨小时的情况 seconds = [time_to_seconds(t) for t in times] processed = [] prev = seconds[0] processed.append(prev) for s in seconds[1:]: # 若当前时间秒数小于前一个,说明跨了1小时,加3600秒 if s < prev: s += 3600 processed.append(s) prev = s return processed # 创建主窗口 root = tk.Tk() root.title("列车运行轨迹图") # 创建绘图画布 canvas = tk.Canvas(root, width=600, height=550, bg="white") canvas.pack() # 站点配置:名称与x轴位置 stations = ["Station 1", "Station 2", "Station 3"] x_positions = [100, 300, 500] # 绘制坐标轴 # X轴(站点轴) canvas.create_line(50, 500, 550, 500, width=2) for x, name in zip(x_positions, stations): canvas.create_line(x, 500, x, 490, width=2) canvas.create_text(x, 520, text=name) # Y轴(时间轴,0-3600秒) canvas.create_line(50, 50, 50, 500, width=2) for sec in range(0, 3601, 300): y = 500 - (sec / 3600) * 450 # 反转Y轴,时间越早位置越靠上 canvas.create_line(45, y, 50, y, width=2) mm, ss = divmod(sec, 60) canvas.create_text(20, y, text=f"{mm:02d}:{ss:02d}") # 列车数据与颜色配置 train_data = { "A": [":35:00", ":38:18", ":45:06"], "B": [":55:06", ":59:12", ":06:18"], "C": [":12:00", ":18:12", ":23:18"] } train_colors = {"A": "red", "B": "blue", "C": "green"} stop_duration = 42 # 停靠时间(秒) # 绘制各列车轨迹 for train_name, times in train_data.items(): processed_sec = process_time_series(times) color = train_colors[train_name] prev_y = None prev_x = None for idx in range(len(processed_sec)): current_x = x_positions[idx] current_sec = processed_sec[idx] current_y = 500 - (current_sec / 3600) * 450 # 绘制站点到达标记 canvas.create_oval(current_x-5, current_y-5, current_x+5, current_y+5, fill=color) canvas.create_text(current_x+15, current_y, text=f"{train_name}\n{times[idx][1:]}", fill=color) # 绘制轨迹线段(包含停靠段) if idx > 0: # 上一站的离开时间 = 到达时间 + 停靠时长 prev_depart_sec = processed_sec[idx-1] + stop_duration prev_depart_y = 500 - (prev_depart_sec / 3600) * 450 # 绘制停靠垂直线段 canvas.create_line(prev_x, prev_y, prev_x, prev_depart_y, width=2, fill=color) # 绘制区间运行线段 canvas.create_line(prev_x, prev_depart_y, current_x, current_y, width=2, fill=color) prev_x, prev_y = current_x, current_y root.mainloop()
关键处理说明
- 时间补正:通过
process_time_series函数,当后续时间的秒数小于前一个时,自动加3600秒(1小时),确保时间序列始终递增,避免线段反向穿越。 - Y轴反转:Tkinter画布的Y轴向下递增,通过
500 - (sec / 3600) * 450将时间秒数转换为画布坐标,让更早的时间显示在图表上方。 - 停靠逻辑:每个站点到达后,绘制一段垂直线段表示42秒的停靠时间,再连接到下一站的到达时间,贴合实际运行场景。
内容的提问来源于stack exchange,提问作者Lisa De Jong
相关产品推荐
相关产品推荐

