Pygal含datetime的图表处理1970年前日期时抛出错误
解决Pygal中1970年前日期在XY图报错的问题
问题根源
你遇到的这个报错,本质是Pygal默认处理datetime/date对象时,会把它们转换成Unix时间戳(从1970-01-01 UTC开始计算的秒数),而1970年之前的日期会生成负的时间戳。Pygal生成的SVG内嵌JavaScript代码在解析这些负时间戳时容易出问题,导致渲染失败,就出现了你看到的回溯报错。
三种可行的解决方案
方案1:直接用字符串表示日期,自定义x轴标签
这种方法最简单,跳过Pygal的日期自动转换,直接用日期字符串作为x轴数据,再手动设置标签:
import pygal from datetime import date # 准备数据,日期用字符串格式存储 data = [ ('1965-01-01', 10), ('1968-05-15', 20), ('1972-09-30', 30) ] # 创建XY图实例 datetimeline = pygal.XY() datetimeline.title = '1970年前日期测试' # 添加数据:直接传入(日期字符串,数值)的元组 datetimeline.add('测试系列', [(date_str, value) for date_str, value in data]) # 自定义x轴标签,设置旋转角度避免重叠 datetimeline.x_labels = [date_str for date_str, _ in data] datetimeline.x_label_rotation = 45 # 渲染到SVG文件 datetimeline.render_to_file('pre_1970_dates.svg')
方案2:将日期转换为基准日以来的天数(正数)
如果需要保持日期的数值排序特性,可以把日期转换成相对于某个更早基准日的天数(这样得到的都是正数),再自定义x轴显示原始日期:
import pygal from datetime import date, timedelta # 设定一个早于所有数据日期的基准日,比如1900年1月1日 base_date = date(1900, 1, 1) # 定义转换函数:日期转成基准日以来的天数 def date_to_days(target_date): return (target_date - base_date).days # 原始数据(带date对象) raw_data = [ (date(1960, 2, 1), 15), (date(1967, 7, 22), 25), (date(1975, 11, 5), 35) ] # 转换数据为(天数,数值)的元组 converted_data = [(date_to_days(d), val) for d, val in raw_data] # 创建XY图 datetimeline = pygal.XY() datetimeline.title = '1970年前日期测试(基于1900年的天数)' # 添加转换后的数据 datetimeline.add('测试系列', converted_data) # 自定义x轴:标签显示原始日期,刻度对应转换后的天数 datetimeline.x_labels = [d.strftime('%Y-%m-%d') for d, _ in raw_data] datetimeline.x_labels_major = [date_to_days(d) for d, _ in raw_data] # 渲染输出 datetimeline.render_to_file('pre_1970_days.svg')
方案3:升级Pygal到最新版本
部分旧版本的Pygal存在负时间戳处理的bug,你可以尝试升级到最新版,看是否能直接解决:
pip install --upgrade pygal
不过要注意:即使升级后,不同浏览器对负时间戳的JavaScript解析支持可能有差异,所以前两种方法的兼容性更稳定。
内容的提问来源于stack exchange,提问作者Patrick Dennis
相关产品推荐
相关产品推荐

