上一篇教程我们完成了折线的绘制。
不过像太阳黑子活动信息这样的折线图,仅仅有折线是不够的。
示例效果:
实际上,我们是想完成像上图这样的一个折线图。
x轴方向标示了时间,y轴方向是每个时间段的数值。
并且,这个图是通过文件生成的。
例如,从我们下载数据的地址所指向的在线文件生成。
那么,通过文件生成一张折线图,我们需要做到以下几点:
1、导入需要用到的模块。
因为需要打开在线的文件,所以需要使用到urllib模块。
绘图以及生成PDF文件依然使用reportlab模块。
示例代码:
'''
想要学习Python?Python学习交流群:984632579满足你的需求,资料都已经上传群文件,可以自行下载!
'''
from reportlab.graphics.shapes import *
from reportlab.graphics import renderPDF
from reportlab.graphics.charts.lineplots import LinePlot
from urllib.request import urlopen
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
2、添加中文支持。
参考上一篇教程的方法,注册需要使用的字体。
pdfmetrics.registerFont(TTFont('msyh', 'msyh.ttf')) # 注册要使用的字体
3、获取在线文件的数据
这里,我们可以先创建一个空列表,用于保存图表数据。
然后,通过urllib模块去获取数据,并通过循环把指定数据添加到列表中。
这里要注意,读取在线文件时,读取到的每行数据都需要解码,不然会以ASCII码的形式存在。
例如当前一行只有一个“#”,通过print()函数显示输出的话,会显示“35”这个数值。
经过解码之后的内容和我们看到的原始文档差不多,只不过都是以“b”开头(bytes类型)的字符串。
不过,这些文件内容有些我们需要,有些不需要。
如上图所示,不需要的内容和需要的内容区别在于:不需要的内容首位字符是“:”或者“#”。
所以,在代码中我们需要判断每一行数据的第一个字符是否“:”或“#”,不是的话再把数据添加到列表中。
最后,还要注意数据之间是空格分隔,我们需要让它们变成以逗号“,”分隔的元组。
示例代码:
'''
想要学习Python?Python学习交流群:984632579满足你的需求,资料都已经上传群文件,可以自行下载!
'''
data = []
for line in urlopen(r'ftp://ftp.swpc.noaa.gov/pub/weekly/Predict.txt'): # 打开在线文件并循环读取每一行
line = line.decode('ascii') # 读取到的内容需要进行解码
if line[0] not in [':', '#']: # 判断首位字符不是指定字符之一
data.append(line.split()) # 以逗号分隔每行内容并添加到列表
4、创建画布,并创建数值轴(y轴)和时间轴(x轴)的列表。
示例代码:
draw = Drawing(400, 240)
predict = [float(row[2]) for row in data] # 创建预测线数值列表
high = [float(row[3]) for row in data] # 创建最高线数值列表
low = [float(row[4]) for row in data] # 创建最低线数值列表
times = [float(row[0]) + float(row[1]) / 12 for row in data] # 创建时间轴数值列表
这里有一点需要注意,每一个列表推导式中的值都需要转换为float类型,不然会导致后方代码在运行时出现异常。
5、创建图表
这里我们使用LinePlot类进行图表的创建,这个类能够让我们方便的通过数据自动生成图表,而无需自己绘制。
我们要做的有以下几步:
示例代码:
chart = LinePlot()
chart.data = [tuple(zip(times, predict)), tuple(zip(times, high)), tuple(zip(times, low))] # 混合列表数据添加到图表
chart.lines[0].strokeColor = colors.green # 设置预测线颜色
chart.lines[1].strokeColor = colors.red # 设置最高线颜色
chart.lines[2].strokeColor = colors.blue # 设置最低线颜色
chart.width = 320 # 设置图表宽度
chart.height = 180 # 设置图表高度
chart.x = 40 # 设置图表整体x轴坐标
chart.y = 30 # 设置图表整体y轴坐标
chart.xValueAxis.valueStep = 1 # 设置图表时间轴步进间隔
这里也有一点要注意,添加数据时要把混合后的zip类型转换为tuple类型。
6、设置标题
标题的设置比较简单,上一篇教程中的开始部分就已经做过,如果忘记了,看一下代码中的注释即可。
示例代码:
title = String(200, 220, '太阳黑子活动信息图') # 创建文本对象
title.fontName = 'msyh' # 设置文本字体
title.fontSize = 14 # 设置文本字号
title.fillColor = colors.gray # 设置文本颜色
title.textAnchor = 'middle' # 设置文本位置的锚点
7、将图表和标题添加到画布并生成PDF文件。
draw.add(chart)
draw.add(title)
renderPDF.drawToFile(draw, 'chart02.pdf', '太阳黑子活动信息')
通过以上步骤,我们就完成了这个示例的编写。