上一篇教程我们完成了折线的绘制。
不过像太阳黑子活动信息这样的折线图,仅仅有折线是不够的。
示例效果:
实际上,我们是想完成像上图这样的一个折线图。
x轴方向标示了时间,y轴方向是每个时间段的数值。
并且,这个图是通过文件生成的。
例如,从我们下载数据的地址所指向的在线文件生成。
那么,通过文件生成一张折线图,我们需要做到以下几点:
- 支持中文内容
- 打开在线文件获取指定的内容
- 绘图(创建画布、图表以及标题)
- 生成PDF
1、导入需要用到的模块。
因为需要打开在线的文件,所以需要使用到urllib模块。
绘图以及生成PDF文件依然使用reportlab模块。
示例代码:
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类型)的字符串。
不过,这些文件内容有些我们需要,有些不需要。
如上图所示,不需要的内容和需要的内容区别在于:不需要的内容首位字符是“:”或者“#”。
所以,在代码中我们需要判断每一行数据的第一个字符是否“:”或“#”,不是的话再把数据添加到列表中。
最后,还要注意数据之间是空格分隔,我们需要让它们变成以逗号“,”分隔的元组。
示例代码:
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类进行图表的创建,这个类能够让我们方便的通过数据自动生成图表,而无需自己绘制。
我们要做的有以下几步:
- 实例化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', '太阳黑子活动信息')
通过以上步骤,我们就完成了这个示例的编写。
本节练习源代码:【点此下载】
转载请注明:魔力Python » 练习项目04:绘制生成PDF折线图(下)