接下的帖子给几个加了注释的折线图代码,代码改自reportlab官方网站。最近跟世界人民一起困在疫情中,共同祈求瘟神快些离开放过人类!进度相当相当慢,琐事缠身可自用的时间非常有限,没有余力回答网友的问题,见谅????
这个折线图加了背景色,x坐标轴采用的是日期坐标轴(年份的后两位),y轴上不仅有格子线,还有子格子线,图例颜色对应采用自动模式。代码注释中有些之前帖子提到过的属性没再标注:
"加了背景色,日期坐标轴,图例颜色对应采用自动模式的折线图"
from reportlab.lib.colors import purple, PCMYKColor, black
from reportlab.graphics.charts.lineplots import LinePlot
from reportlab.graphics.charts.legends import LineLegend
from reportlab.graphics.shapes import Drawing, _DrawingEditorMixin, Rect
from reportlab.lib.validators import Auto
from reportlab.graphics.charts.axes import NormalDateXValueAxis
class LineChart_withBackgroundColor(_DrawingEditorMixin,Drawing):
'''
折线图特点
============
- 背景用了个长方形,长方形坐标和大小刚好切合画板大小
- x坐标轴采用日期轴
- 图例用LineLegend类生成的对象legend,LineLegend是Legend的子类
- legend.colorNamePairs赋的值是基于图表自身的颜色和数据线name属性的自动模式
- 自动模式根据数据线的颜色和名字属性自动生成对应图例,不必像之前那样要自己手动设置色块和项目的关系
'''
def __init__(self,width=400,height=200,*args,**kw):
Drawing.__init__(self,width,height,*args,**kw)
fontName = 'Helvetica'
self.width = 298
self.height = 164
self.background = Rect(0, 0, self.width, self.height, strokeWidth=0, fillColor=PCMYKColor(0,0,0,0))
# 背景长方形周线的颜色、宽度和图案
self.background.strokeColor = black
# 长方形边框的颜色
self.background.strokeWidth = 3
# 长方形边框线的宽度
self.background.strokeDashArray = (3, 2)
# 长方形边框线的格式,3点实线2点虚线
self.background.fillColor = PCMYKColor(66, 13, 0, 22)
self.background.x = 0
self.background.fillOpacity = 0.5 # 色彩透明度
self._add(self,LinePlot(),name='chart',validate=None,desc=None)
self.chart.xValueAxis = NormalDateXValueAxis()
self.chart.xValueAxis.labels.boxAnchor = 'autox'
# 默认值是'n'
self.chart.xValueAxis.labels.fontName = fontName
self.chart.xValueAxis.labels.fontSize = 8
self.chart.xValueAxis.labels.rightPadding = 2
# 右留白
self.chart.xValueAxis.xLabelFormat = '{yy}'
# 只显示年份后两位
self.chart.xValueAxis.strokeWidth = 0
# 为0时,如果visibleAxis为1会有一条浅浅的轴线
self.chart.xValueAxis.visibleAxis = 0
# 默认1,可见
self.chart.xValueAxis.visibleTicks = 0
# 刻度不可见
self.chart.xValueAxis.maximumTicks = 30
# 最多刻度可以到30个
self.chart.xValueAxis.forceFirstDate = 1
# 默认是0,是否强制显示第一个日期
self.chart.yValueAxis.visibleGrid = 1
# 显示格线
self.chart.yValueAxis.gridStrokeWidth = 0.25
# 格线宽度
self.chart.yValueAxis.gridStrokeColor = PCMYKColor(100, 100, 100, 100)
self.chart.yValueAxis.visibleSubGrid = 1
# 显示子格线
self.chart.yValueAxis.subTickNum = 2
# 每个格子grid里有几条子格线
self.chart.yValueAxis.subGridStrokeColor = purple
# 子格线的颜色
self.chart.yValueAxis.subGridStrokeWidth = 0.1
# 子格线的宽度
# self.chart.yValueAxis.subGridStart = 10
# 设置子格线的起点
# self.chart.yValueAxis.subGridEnd = 50
# 设置子格线的终点
self.chart.yValueAxis.visibleAxis = 0
# y轴不可见
self.chart.yValueAxis.visibleTicks = 0
# y轴刻度不可见
self.chart.yValueAxis.labels.fontName = fontName
self.chart.yValueAxis.labels.fontSize = 8
self.chart.yValueAxis.labelTextFormat = '%0.0f'
# y轴上标签的格式
self.chart.yValueAxis.labels.rightPadding = 5
self.chart.yValueAxis.labelTextScale = 1
# Scaling for label tick values
self.chart.yValueAxis.labels.fillColor = black
self.chart.yValueAxis.labels.dx = 3
self.chart.yValueAxis.maximumTicks = 15
self.chart.yValueAxis.rangeRound ='both'
# OneOf('none','both','ceiling','floor'),'How to round the axis limits'
self.chart.yValueAxis.avoidBoundFrac = 0.1
# Fraction of interval to allow above and below.
self.chart.yValueAxis.forceZero = 1
self.chart.yValueAxis.visible = 1
# 显示yValueAxis这个对象,除非某部分特别说明不显示(visibleAxis、
# visibleLabels、visibleTicks、visibleGrid)
# sample data
self.chart.data = [
[(19910301, 94.260000000000005), (19910301, 102.25), (19920301, 101.47), (19930301, 134.84999999999999),
(19940301, 121.52), (19950301, 145.87), (19960301, 166.0), (19970301, 172.91),
(19980301, 212.83000000000001), (19990301, 391.86000000000001), (20000301, 267.38999999999999),
(20010301, 218.22), (20020301, 161.50999999999999), (20030301, 211.46000000000001), (20040301, 245.16),
(20050301, 278.97000000000003), (20060301, 337.45999999999998), (20070301, 392.66000000000003),
(20080301, 357.25)],
[(19910301, 94.319999999999993), (19910301, 100.36), (19920301, 87.530000000000001), (19930301, 109.78),
(19940301, 114.98999999999999), (19950301, 128.38999999999999), (19960301, 133.13999999999999),
(19970301, 136.24000000000001), (19980301, 166.84999999999999), (19990301, 216.41), (20000301, 163.62),
(20010301, 123.68000000000001), (20020301, 104.19), (20030301, 138.03), (20040301, 160.78),
(20050301, 182.69999999999999), (20060301, 215.40000000000001), (20070301, 250.84), (20080301, 230.37)]]
sNames = 'Shell Transport & Trading', 'Liberty International'
colorsList = PCMYKColor(100, 0, 90, 50), PCMYKColor(0, 100, 100, 40)
for i in range(len(self.chart.data)):
self.chart.lines[i].name = sNames[i]
# 图表上每条数据线的名字
self.chart.lines[i].strokeColor = colorsList[i]
# 数据线的颜色
self.chart.lines.strokeWidth = 2 # 数据线的宽度
self.chart.width = 265
self.chart.height = 95
self.chart.y = 55
self.chart.x = 23
self._add(self,LineLegend(),name='legend',validate=None,desc=None)
self.legend.colorNamePairs = Auto(obj=self.chart)
# 图例开启自动模式,用数据线上的一小段做色块,一一对应chart.lines各数据线的名字name属性
self.legend.x = 6
self.legend.y = 30
self.legend.dx = 6
# 图例线段标识(原色块的位置)的长度
self.legend.dy = 10
# 当LineLegend对象选用Auto模式,会自动采用数据线上一小截或数据线上标记Marker
# 做图例标识(原色块的位置),此时dy可用来调整图例y轴方向的位置
self.legend.fontName = fontName
self.legend.fontSize = 8
self.legend.alignment ='right'
self.legend.columnMaximum = 3
self.legend.dxTextSpace = 4
self.legend.variColumn = 1
self.legend.boxAnchor = 'nw'
self.legend.deltay = 10
self.legend.autoXPadding = 65
# 当deltax=None时,列间x方向的留白
# 这里不起作用,因为没有设置deltax=None,deltax默认值为75
self.height = 164
if __name__=="__main__": #NORUNTESTS
LineChart_withBackgroundColor().save(formats=['pdf'],outDir='.',fnRoot=None)