Reportlab生成PDF文件

接下的帖子给几个加了注释的折线图代码,代码改自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)