PythonとReportLabでPDFに散布図を追加する

備忘録ヘッダ画像 プログラミング備忘録

ReportLabでPDFに散布図を追加するコードを作ったので、後でコピペできるように残しておく。
使いそうなプロパティにはコメントで用途をメモ書きしておいた。

コード

from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import A6,  landscape
from reportlab.lib.units import mm
from reportlab.lib import colors
from reportlab.graphics.shapes import Drawing
from reportlab.graphics import renderPDF

from reportlab.graphics.charts.lineplots import ScatterPlot

def main():
    # A6(横)の新規PDFファイルとして初期化 使いたいサイズをpagesizesからimportする
    p = canvas.Canvas("scatter_plot.pdf", pagesize=landscape(A6))

    # 描画するデータ まとまったタプルごとにグループになるっぽい。マーカの形が同じになる
    data = [[(2.25, 4.48),(3.59, 4.42),(4, 3),(4, 4),],  
            [(5.52, 2.7),],
            [(8.6, -2.82),(7.1, -1.5),],]

    # 散布図描画関数
    createScatterPlot(p, data)

    # 保存
    p.showPage()
    p.save()


def createScatterPlot(pdf, data):
    drawing = Drawing(300, 200) # 描画領域の枠線とか表示しないなら、サイズ指定しなくてもいいと思う
    sp = ScatterPlot()
    sp.x = 10*mm    # 描画領域の原点からのグラフ位置
    sp.y = 10*mm    # importしたmmをかけることでミリ単位から良きに変換しくれる

    sp.height = 50*mm   # グラフサイズ
    sp.width  = 80*mm

    sp.data = data # 描画対象のデータをセット

    # X軸目盛設定
    sp.xValueAxis.valueMin = 0      # 最小値
    sp.xValueAxis.valueMax = 10     # 最大値
    sp.xValueAxis.visibleTicks = 1  # 目盛線表示設定 0 or 1
    sp.xValueAxis.visibleLabels = 1 # ラベル表示設定 0 or 1
    sp.xValueAxis.visibleGrid = 1   # グリッド線表示設定 0 or 1
    sp.xValueAxis.valueStep = 1     # 目盛の間隔
    sp.xValueAxis.strokeWidth = 0.1 # X軸線太さ

    # X軸グリッド線の設定
    sp.xValueAxis.gridStrokeColor = colors.red  # グリッド線色
    sp.xValueAxis.gridStrokeWidth = 0.5         # グリッド線太さ
    sp.xValueAxis.gridStrokeDashArray =  (2, 1) # グリッド破線描画の破線の実線と空白の長さをそれぞれ指定
    
    # Y軸目盛設定
    sp.yValueAxis.valueMin = -10     # 最小値
    sp.yValueAxis.valueMax = 10      # 最大値
    sp.yValueAxis.valueStep = 5      # 目盛の間隔
    sp.yValueAxis.visibleGrid = 1    # グリッド線表示設定 0 or 1
    sp.yValueAxis.visibleTicks = 1   # 目盛線表示設定 0 or 1
    sp.yValueAxis.labels.visible = 1 # ラベル表示設定 0 or 1

    # Y軸グリッド線の設定
    sp.yValueAxis.gridStrokeColor = colors.blue
    sp.yValueAxis.gridStrokeWidth = 0.5
    sp.yValueAxis.gridStrokeDashArray =  (2, 1)
    

    # 軸のタイトルを設定 ※日本語を使いたいときは CanvasオブジェクトのsetFont関数で日本語対応のフォントを設定しておく
    sp.xLabel = "X axis title"
    sp.yLabel = "Y axis title"

    drawing.add(sp) 

    # グラフをPDFに描画
    x = 10 * mm # PDF上の描画位置 
    y = 10 * mm # PDF上の描画位置
    renderPDF.draw(drawing, pdf, x, y, showBoundary=True) # showBoundaryでDrawing描画領域の枠線を出すか決める

if __name__=="__main__":
    main()
実行結果

コードと同じ階層にscatter_plot.pdfが生成される。

ReportLabでPDFに散布図
マーカーの形をカスタマイズする

先ほどのコードのScatterPlotオブジェクト(変数名sp)に対して、マーカーの設定を追加する場合のコード。

    # マーカ設定
    sp.lineLabelFormat="%.2f"   # マーカラベル文字列のフォーマッタ
    sp.lineLabels.fontSize = 5  # マーカラベルフォントサイズ
    sp.lineLabelNudge = 0   # データポイントとそのラベルの間の距離?
    sp.lines.symbol=makeMarker('FilledCircle',size=1)
    sp.lines[1].symbol=makeMarker('FilledDiamond',size=2)
    sp.lines[2].symbol=makeMarker('Square',size=5)
    sp.lines[2].symbol.strokeColor = colors.red     # マーカの枠線色
    sp.lines[2].symbol.fillColor = colors.yellow    # マーカの塗りつぶし色
    sp.lines[2].symbol.strokeWidth = 2       # マーカの枠線太さ
    sp.lines[2].symbol.angle = 14            # マーカの傾き

    # makeMarkerのマーカースタイル
    # 'Square', 'Diamond', 'Circle', 'Cross', 'Triangle', 'StarSix',
    # 'Pentagon', 'Hexagon', 'Heptagon', 'Octagon', 'StarFive',
    # 'FilledSquare', 'FilledCircle', 'FilledDiamond', 'FilledCross',
    # 'FilledTriangle','FilledStarSix', 'FilledPentagon', 'FilledHexagon',
    # 'FilledHeptagon', 'FilledOctagon', 'FilledStarFive',
    # 'Smiley','ArrowHead', 'FilledArrowHead'

グラフのサイズをすごく縦長にして出してみたのであまり散布図らしい見た目ではないが、マーカーは以下のような感じで結構自由が利く。またラベルの文字列にフォーマッタを設定したので、少数以下3桁までのラベル表示になっている。

ReportLabで散布図のマーカを変更
タイトルとURLをコピーしました