25 带表格的直方图(BarChart)
- 使用类TableWidget生成的对象添加表格列出直方图数据柱代表的数据
- 数据柱指定填充颜色,带黑边
- 两种情况下不显示数据柱标签,一个是设置直方图的barLabels.visible为False(默认为True),一个是直方图的self.chart.barLabelFormat为None(默认就是None)
"带表格的直方图"
from reportlab.lib.colors import PCMYKColor, black, red
from reportlab.graphics.charts.legends import Legend
from reportlab.graphics.shapes import Drawing, _DrawingEditorMixin, String, Line
from reportlab.lib.validators import Auto
from reportlab.graphics.widgets.table import TableWidget
from reportlab.lib.formatters import DecimalFormatter
from reportlab.graphics.charts.barcharts import VerticalBarChart
class BarChart_Table(_DrawingEditorMixin,Drawing):
def __init__(self,width=403,height=163,*args,**kw):
Drawing.__init__(self,width,height,*args,**kw)
fontName = 'Helvetica'
fontSize = 5
bFontName = 'Times-Bold' # 刻度标签和表格中的字体
bFontSize = 7 # 刻度标签和表格中的字体大小
self._add(self,VerticalBarChart(),name='chart',validate=None,desc=None)
self.chart.height = 73
self.chart.width = 250
self.chart.fillColor = PCMYKColor(0, 3, 7, 6) # 图表的背景色
self.chart.data = \
[[7.7199999999999998, 7.9400000000000004, 9.1699999999999999, 7.04, 7.7199999999999998, 8.1699999999999999],
[4.46, 1.97, 13.220000000000001, 10.49, 8.5800000000000001, 10.74],
[5.1399999999999997, 9.5999999999999996, 5.3099999999999996, 4.4699999999999998, 3.5099999999999998, 4.8399999999999999]]
# 数据柱周线的宽度和颜色
self.chart.bars.strokeWidth = 0.5
self.chart.bars.strokeColor = PCMYKColor(0,0,0,100)
self.chart.barWidth = 2
self.chart.barSpacing = 0.5 # 同组数据柱的间距
self.chart.groupSpacing = 5 # 组与组的间距
# 指定数据柱的颜色
colorsList = [PCMYKColor(0, 73, 69, 56), PCMYKColor(23,51,0,4),
PCMYKColor(41, 25, 0, 21)]
for i, color in enumerate(colorsList):
self.chart.bars[i].fillColor = color
# 设置数据轴(y轴)的属性
self.chart.valueAxis.labels.fontName = fontName # 刻度标签的字体和字体大小
self.chart.valueAxis.labels.fontSize = fontSize
self.chart.valueAxis.visibleGrid = False # 格子线不可见
self.chart.valueAxis.visibleTicks = False # 刻度线不可见
self.chart.valueAxis.strokeWidth = 0.25 # 轴线宽度
self.chart.valueAxis.avoidBoundFrac = 0 # 影响数轴刻度值表达范围
# self.chart.valueAxis.avoidBoundFrac = 1
self.chart.valueAxis.rangeRound ='both'
self.chart.valueAxis.labelTextFormat = None # 刻度的格式
# self.chart.valueAxis.labelTextFormat = DecimalFormatter(1, suffix=None, prefix=None)
self.chart.valueAxis.forceZero = True # 强制显示0刻度
self.chart.valueAxis.labels.boxAnchor = 'e' # 刻度标签的锚点
self.chart.valueAxis.labels.dx = -1 # 微调刻度标签的位置
# 设置类别轴(x轴)的属性
self.chart.categoryAxis.visibleGrid = False # 格子线不可见
self.chart.categoryAxis.visibleTicks = False # 刻度线不可见
self.chart.categoryAxis.strokeWidth = 0.25 # 轴线宽度
self.chart.categoryAxis.labelAxisMode ='low' # 刻度标签显示在图表底部
# self.chart.categoryAxis.labelAxisMode ='high' # 刻度标签显示在图表顶部
# self.chart.categoryAxis.labelAxisMode ='axis' # 刻度标签显示在坐标轴
# self.chart.categoryAxis.labelAxisMode ='axispmv' # 刻度标签显示在坐标轴附近
self.chart.categoryAxis.labels.fillColor = black # 刻度标签的颜色
# self.chart.categoryAxis.labels.fillColor = red
self.chart.categoryAxis.labels.angle = 0 # 刻度标签的角度
self.chart.categoryAxis.labels.fontName = bFontName # 刻度标签的字体和字体大小
self.chart.categoryAxis.labels.fontSize = bFontSize
self.chart.categoryAxis.labels.boxAnchor = 'e' # 刻度标签的锚点
self.chart.categoryAxis.labels.dx = 7 # 微调刻度标签的位置
self.chart.categoryAxis.labels.dy = -5
self.chart.categoryAxis.categoryNames = ['200%d'%i for i in range(1,7)]
# 列表的每个元素是一个字符串'200%d',%d的位置放一个数字,数字是循环变量i,从1到6
self._add(self,Legend(),name='legend',validate=None,desc=None)
self.legend.fontName = fontName
self.legend.fontSize = fontSize
self.legend.strokeWidth = 0.5
self.legend.strokeColor = PCMYKColor(0,0,0,100)
self.legend.dx = 8 # 色宽的宽高
self.legend.dy = 5
self.legend.variColumn = True # 列宽可变
self.legend.subCols.minWidth = self.chart.width/2 # 最小列宽
self.legend.dxTextSpace = 5 # 色块与文字间距
self.legend.deltax = 0 # 色块之间x方向间距
self.legend.deltay = 8 # 色块之间y方向间距
self.legend.alignment = 'right' # 文字在色块右边
self.legend.columnMaximum = 3 # 每一列最多3行
self.legend.boxAnchor = 'sw' # 锚点在西南角(sw)
self.legend.colorNamePairs = Auto(obj=self.chart)
# 启动自动模式配置色块与文字的对应关系,前提是有对bars[i].name赋值(后面又做)
self._add(self,TableWidget(),name='table',validate=None,desc=None)
# 表格周线的颜色和宽度
self.table.borderStrokeColor = PCMYKColor(0, 12, 24, 36)
self.table.borderStrokeWidth = 0.5
# 表格填充色
self.table.fillColor = PCMYKColor(0, 3, 7, 6)
# 表格内部水平垂直格线的颜色和宽度
self.table.horizontalDividerStrokeColor = PCMYKColor(0, 12, 24, 36)
self.table.horizontalDividerStrokeWidth = 0.5
# 垂直线不显示
self.table.verticalDividerStrokeColor = None
self.table.verticalDividerStrokeWidth = 0
self.table.dividerDashArray = None # 没有虚线样式
# 设置表格内容
self.table.data = [['BP', None] + self.chart.data[0],
['Shell Transport & Trading', None] + self.chart.data[1],
['Liberty International', None] + self.chart.data[2]]
# 有None是为了给第一列多些空间
self.table.boxAnchor = 'sw' # 表格锚点
self.table.fontName = bFontName # 表格内字体和字体大小
self.table.fontSize = bFontSize
self.table.fontColor = black # 表格内文字的颜色
self.table.height = 45
self.table.width = 400
for i in range(len(self.chart.data)):
self.chart.bars[i].name = self.table.data[i][0]
# 赋值每个数据柱的name属性
# 调整各部分的位置和大小
self.width = 400
self.height = 200
self.chart.y = 75
self.chart.x = 140
self.legend.x = 24
self.legend.y = 75
self.table.x = 0
self.table.y = 0
if __name__=="__main__":
BarChart_Table().save(formats=['pdf'],outDir='.',fnRoot=None)