用Reportlab生成PDF文件中的图表,碰到以下情况:
直接在图表上标注不可行,此时可以用Legend生成专门的图例:
from reportlab.graphics.charts.piecharts import Pie # Pie型图表
from reportlab.lib.colors import HexColor, black, red, purple, green, maroon, brown, pink, white, HexColor
from reportlab.graphics.charts.legends import Legend # 图例
from reportlab.graphics.shapes import Drawing
from myStyle import * # 在myStyle.py里有自己注册的中文字体
# 指定图例中用到的颜色序列
pdf_chart_colors = [
HexColor("#8900c9"), HexColor("#60955f"), HexColor("#5757f0"),
HexColor("#8f8ff5"), HexColor("#c7c7fa"), HexColor("#f5c2c2"),
HexColor("#eb8585"), HexColor("#e04747"), HexColor("#d60a0a"),
HexColor("#ce3c7b"), HexColor("#f84031"), ]
# 指定画布的宽高,图表图例都画在画布上
width = 400
height = 200
d = Drawing(width, height)
# 指定图表的宽高
pc = Pie()
pc.width = 150
pc.height = pc.width
# 图表左下角的坐标
pc.x = 20
pc.y = (height-pc.height)/2
# 图表表现的数据
pc.data = [11.90,13.30,11.10,9.40,8.50,7.80,7.00,6.20,8.80,4.00]
# 图表的标签
pc.labels = ['翠云山芭蕉洞','平顶山莲花洞','万寿山五庄观','积雷山摩云洞','斜月三星洞','号山火云洞','兜率宫','广寒宫','凌霄殿','披香殿']
# 图表的标签不在图表上显示,而是另行在图例上显示
pc.slices.label_visible = 0
# 图表上线的颜色和宽度
pc.slices.strokeColor = white
pc.slices.strokeWidth = 1
# 指定图表上颜色到颜色列表里取色的循环模式
m = len(pdf_chart_colors) # 可取的颜色个数
n = len(pc.data) # 需要的颜色个数
i = m // n # i是整除后的值,决定取颜色时间隔几个取
for j in range(n):
setattr(pc.slices[j], 'fillColor', pdf_chart_colors[j * i % m])
# 填色时不是顺序取色,而是跳着取,跳得幅度跟i有关,隔2个、3个……取
d.add(pc) # 将图表添加进画布
myLegend = Legend() # 生成图例对象
# 指定图例锚点的位置
myLegend.x = 200 # 横坐标
myLegend.y = height/2 # 纵坐标
myLegend.dx = 8 # 图例上颜色块的宽度
myLegend.dy = 8 # 颜色块的高度
myLegend.fontName = 'apple'
# 指定图例上的字体,apple是自己在myStyle.py里定义的中文字体
myLegend.fontSize = 7 # 字体大小
myLegend.boxAnchor = 'w' # 图例的锚点,w-west
myLegend.columnMaximum = 15 # 图例最多显示几行
myLegend.strokeWidth = 1 # 线条宽度
myLegend.strokeColor = black # 线条颜色
myLegend.deltay = 10 # 图例上的行间距
myLegend.yGap = 0 # 跟前面的参数一起调节行间距
myLegend.dxTextSpace = 10 # 图示文字和色标的间距
myLegend.alignment = 'right' # 图示说明文字在颜色图示的右边
myLegend.dividerLines = 1|2|4
# 1是行与行之间有线,2是最顶的线,4是最底的线
myLegend.dividerOffsY = 4.5
# Y轴方向上调整间隔线的位置
myLegend.subCols.rpad = 30
# 图示文字和数字之间增加了30的间隔
myLegend.colorNamePairs = [(pc.slices[i].fillColor,
(pc.labels[i], '{:.2f}'.format(pc.data[i]))) for i in range(n)]
# 指定图例上的填色块、图例上的标签和对应的数字,n是图例表达的数据个数
d.add(myLegend) # 将图例添加进画布
from reportlab.graphics import renderPDF
renderPDF.drawToFile(d, 'pieChartLegend.pdf') # 写入PDF文件
myStyle.py注册中文字体的相关代码:
......
from reportlab.pdfbase.ttfonts import TTFont
from reportlab.pdfbase import pdfmetrics
pdfmetrics.registerFont(TTFont('apple', '/Library/Fonts/Chinese/XiaoHuYao-2.ttf'))
......