【1000个文本绘图技巧-Graphviz005】Graphviz根据日记等结构化时间序列文件自动生成时间序列图?

背景

使用Graphviz自动将格式化日记按照月份生成图片,出来后效果不错。无论日记、未来规划还是其他事情记录都可以使用该种方式。
模式是:将事情按照格式化写入指定文件比如riji.log 然后执行脚本生成Graphviz,将事件自动生成到时间线上面

主体代码

  • 代码
#!/usr/bin/python
# -*- coding: utf-8 -*-
import sys

msi=int(sys.argv[1])
dsi=int(sys.argv[2])
mei=int(sys.argv[3])
dei=int(sys.argv[4])
file_path=sys.argv[5]

year="23"

mdays=[31,28,31, 30,31,30, 31,31,30, 31,30,31]

def gen_mon(msi,mei,dsi,dei):
	print("\nnode [fontsize=20, shape=box, style=filled fillcolor=lightgreen];")
	for m in range(msi, mei+1):
		if m == msi:
			ds=int(dsi)
		else:
			ds=1
		if m==mei:
			de=dei
			if de > mdays[m-1]:
				de = mdays[m-1]
		else:
			de=mdays[m-1]
		print("\n{:>02}.{:>02}".format(year,m))

def gen_day(msi,mei,dsi,dei):
	print("\nnode [fontsize=20, shape=box, style=filled fillcolor=lightgray];")
	for m in range(msi, mei+1):
		if m == msi:
			ds=int(dsi)
		else:
			ds=1
		if m==mei:
			de=dei
			if de > mdays[m-1]:
				de = mdays[m-1]
		else:
			de=mdays[m-1]
		print("\n{:>02}.{:>02}->".format(year,m))
		for i in range(ds, de+1):
			if i!=de:
				print("{:>02}{:>02}->".format(m,i))
			else:
				print("{:>02}{:>02}".format(m,i))


def gen_rank_same(msi,mei,dsi,dei):
	print("# rank")
	print("\nnode [fontsize=20, shape=box, style=filled fillcolor=cyan];")
	for m in range(msi, mei+1):
		if m == msi:
			ds=int(dsi)
		else:
			ds=1
		if m==mei:
			de=dei
			if de > mdays[m-1]:
				de = mdays[m-1]
		else:
			de=mdays[m-1]
		print("\n#{:>02}.{:>02}".format(year,m))
		septimelist=[3,6,9,12]
		seasonlist=[3,6,9,12]
		for i in range(ds, de+1):
			if (m in seasonlist)  and (i == 30):
				print("{ rank=same; %02d%02d -> season_%02d%02d}" %(m,i, m,i))
			elif (m in septimelist) and (i==22):
				print("{ rank=same; %02d%02d -> jieqi_zhifen%02d%02d}" %(m,i, m,i))
			else:
				print("{ rank=same; %02d%02d }" %(m,i))

def gen_head():
	print("digraph timeline {")
	print('size = "7,8";')

def gen_tail():
	print("}")

def _print_riji_event_label(lines):
	# 遍历每一行,打印label
	print("\n# event label")
	for line in lines:
		if len(line) < 10:
			continue
		#     2023-09-12 周一;Graphviz年时间线 def
		ldate=line[5:7]+line[8:10]
		print("\n## " + ldate)

		line=line[10:]
		line = line.replace('\n','').replace(";", ";").replace(",",";") #逗号也是一个分隔符
		la=line.split(';')
		for i in range(0, len(la)):
			if len(la[i]) < 2:
				continue
			if i == 0: #第一个不标数字 是星期
				seq=""
				weekenddaylist=["周六", "周日"]
				la[i]=la[i].replace(" ",'').replace(",", '')
				if la[i] in weekenddaylist:
				    weekendcolor="style=filled fillcolor=lightgreen"
				else:
				    weekendcolor="style=filled fillcolor=coral"
			else:
				seq="{:>02d}:".format(i) 
				weekendcolor=""
			print("d_env_"+ldate + "_" + str(i) + " [label=\"" + seq + la[i] + "\" " + weekendcolor +"];")

def _print_riji_event_ranksame(lines):
	print("\n# ranks=same")
	for line in lines:
		if len(line) < 10:
			continue
		ldate=line[5:7]+line[8:10]

		line=line[9:]
		line = line.replace('\n','').replace(";", ";").replace(",",";") #逗号也是一个分隔符
		la=line.split(';')
		print("{ rank=same; " + ldate),
		for i in range(0, len(la)):
			if len(la[i]) < 2:
				continue
			print("-> d_env_" + ldate + "_" + str(i)),
		print("}")

def gen_riji_event():
	print("\nnode [fontsize=20, shape=box, style=filled fillcolor=lightblue];")
	#读取文件riji.log到list中
	#file_path = "riji.log"
	with open(file_path, "r") as file:
		lines=file.readlines()
	#linearray=lines.split('\n')
	_print_riji_event_label(lines)
	_print_riji_event_ranksame(lines)


def gen_total():
	gen_head()
	gen_mon(msi, mei, dsi, dei)
	gen_day(msi, mei, dsi, dei)
	gen_rank_same(msi, mei, dsi, dei)
	gen_riji_event()
	gen_tail()

def main():
	gen_total()

main()

#python riji.py 9 1 9 31 riji.log > 1.gv

脚本会将周末和工作日进行简单着色区分

  • 测试文件:riji.log
2023-09-10 周日;t10; t10-abc
2023-09-09 周六;t9; ti_kaj;
2023-09-08 周五;t8
2023-09-07 周四;
2023-09-06 周三;
2023-09-05 周二;t5; teat5; 喂马;劈柴;周游世界
2023-09-04 周一;t4
2023-09-03 周日;t3; t3-2
2023-09-02 周六;t2
2023-09-01 周五;test1

文件格式:

日期 星期;事件1;事件2
例子:
2023-09-01 周五;test1
需要用分号隔开

执行和效果

  • 执行:
python riji.py 9 1 9 31 riji.log> 1.gv

指定开始结束日期,以及输出到gv文件,然后生成的dot使用Graphviz打开

  • 效果
    在这里插入图片描述

技巧

  • 可以生成日记图,项目进展图,项目规划图,其他计划图等时间线相关的
  • 将事情按照格式化写入riji.log 然后执行脚本生成Graphviz,将事件自动生成到时间线上面
  • todo: 未来添加年份等自动生成方式
  • 依赖格式化文件
  • 每个item不要有逗号 逗号是一个事件分隔符(为了适配csv)
  • 通过excel编辑 然后导出为csv可以直接使用,csv格式中日期需要以1900-09-10这种方式

综述

Graphviz图形化展示,结合timeline,结合文件自动生成,极大的提高了展示的效率和体感。python自动化生成可以将源数据和展示数据分开显示,这样可以针对很多其他场景极大的提高使用效率。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值