简体   繁体   中英

python reportlab categoryAxis label placement

I've written a simple function that generates a simple bar chart from a single data series as shown below. The input data can be positive or negative, which when negative results in the category axis labels being covered by the bar (charts 2 and 3 in the code below).

I have searched the reportlab graphics reference , and on page 202 a bar chart with labels placed "low" is shown. However the command used to do this: bc.categoryAxis.labels.dy = -60, appears to be arbitrarily chosen. How would one know the negative offset if the input data is not known? Is there a way to identify the x axis location on the drawing and then determine the label offset from that location, or any other work-around when the input data is unknown?

Thanks for any guidance.

from reportlab.graphics.shapes import Drawing
from reportlab.graphics.charts.barcharts import VerticalBarChart
from reportlab.graphics.charts.textlabels import Label
from reportlab.lib import colors
from reportlab.platypus import SimpleDocTemplate
from reportlab.lib.units import inch
from reportlab.lib.pagesizes import letter

def vbar_one_series(data, xlabels, chart_title, xaxis_text):
    drawing = Drawing(180, 180)

    bc = VerticalBarChart()
    bc.x = 25
    bc.y = 25
    bc.height = 125
    bc.width = 150
    bc.data = [data]
    bc.valueAxis.valueMin = int(min(min(bc.data[0]), 0))
    bc.valueAxis.valueMax = int(max(bc.data[0]) + 2)
    bc.valueAxis.labels.fontName = 'Helvetica'
    bc.valueAxis.labels.fontSize = 7
    bc.valueAxis.labelTextFormat = '%0.1f'
    bc.bars[0].fillColor = colors.HexColor('#000035')
    bc.categoryAxis.labels.boxAnchor = 'c'
    bc.categoryAxis.labels.fontName = 'Helvetica'
    bc.categoryAxis.labels.fontSize = 7
    bc.categoryAxis.tickDown = 0
    bc.categoryAxis.labels.dx = 0
    bc.categoryAxis.labels.dy = -7
    bc.categoryAxis.labels.angle = 0

    bc.categoryAxis.categoryNames = xlabels

    bc.barLabels.nudge = 10
    bc.barLabelFormat = '%0.1f'
    bc.barLabels.dx = 0
    bc.barLabels.dy = 0
    bc.barLabels.fontName = 'Helvetica'
    bc.barLabels.fontSize = 7

    xlabel = Label()
    xlabel.setText(xaxis_text)
    xlabel.fontSize = 7
    xlabel.fontName = 'Helvetica'
    xlabel.dx = 90
    xlabel.dy = 5

    title = Label()
    title.setText(chart_title)
    title.fontSize = 7
    title.fontName = 'Helvetica'
    title.dx = 90
    title.dy = 175

    drawing.add(bc)
    drawing.add(xlabel)
    drawing.add(title)

    return drawing

if __name__ == '__main__':

    bar1 = vbar_one_series([1.0, 2.3, 1.8], ['A', 'B', 'C'],
                                 'Title 1', '')

    bar2 = vbar_one_series([-25, 50, 10], ['A', 'B', 'C'],
                           'Title 2', '')

    bar3 = vbar_one_series([0, -1.1, -0.4], ['A', 'B', 'C'],
                           'Title 3', '')

    doc = SimpleDocTemplate('H:/Desktop/report.pdf', pagesize=letter,
                            topMargin=0.5 * inch, bottomMargin=0.5 * inch)
    Catalog = []
    Catalog.append(bar1)
    Catalog.append(bar2)
    Catalog.append(bar3)
    doc.build(Catalog)

report.pdf

经过一些额外的研究,我发现可以使用.categoryAxis.labelAxisMode ='low'属性来解决此问题。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM