【完全版】python エクセルでグラフを作る 解説付き【初心者のためのpython #7】

pythonでエクセル操作
この記事は約14分で読めます。

openpyxlを使って、普段エクセルのプロットでよく使う機能を

pythonで実施できるようになったのでまとめました!

matplotlibでグラフ化してしまうと、python未インストール者に操作しずらい

文句を言われてしまいます。

なので会社ではエクセルプロットすることがすごく大切です!

がんがんコピペで使ってみてください!

勉強させてもらったサイト

openpyxl - A Python library to read/write Excel 2010 xlsx/xlsm files — openpyxl 3.0.4 documentation
【Excel x Python】 openpyxlを使って面倒なExcelのグラフ作成作業を自動化する
openpyxlを使用してExcelのグラフ作成を自動化する方法を紹介します。 Excelのグラフ作成だからといって妥協してVBAを使う必要はありません。openpyxlを使えば、Excelへの書き込みからグラフ作成までPythonで完結します。 無理にVBAを使う必要ありません。openpyxlを使いExcel操作も...

openpyxlを使いエクセルでグラフを書く

pythonでopenpyxlを使う事前準備

こちらの記事でわかりやすくまとめたので参考にしてほしい

使い方【解説付き】

必要なimport

とりあえずこれをすべてimport

import openpyxl
from openpyxl import Workbook, load_workbook
from openpyxl.chart import ScatterChart, LineChart, Reference, Series
from openpyxl.chart.shapes import GraphicalProperties
from openpyxl.chart.layout import Layout, ManualLayout
from openpyxl.chart.text import RichText
from openpyxl.drawing.text import Paragraph, ParagraphProperties, CharacterProperties, Font, RichTextProperties
from openpyxl.drawing.line import LineProperties
from copy import deepcopy

散布図のインスタンスを作成する

ScatterChartのインスタンスを作成しよう

他にもLineChart()なども使うが散布図が使えていれば他はさほど使わないだろう

chart = ScatterChart()

グラフを描画する

グラフを置く位置をセルで指定する。

指定したセルの左上からグラフが表示される

ws.add_chart(作成したチャート, セル)

散布図をプロットする

xvalues = Reference(ws, min_col=列の指定, min_row=行のはじめの指定, max_row=行の終わりの指定)
values = Reference(ws, min_col=列の指定, min_row=行のはじめの指定, max_row=行の終わりの指定)
# グラフ化
series = Series(values, xvalues, title_from_data=True)
# 作成したチャートに追加
chart.series.append(series)

グラフの大きさを変える

# それぞれ数字を代入
chart.height = 15
chart.width = 25

グラフのタイトルを記入する

ochart.title = "sample 散布図"

グラフにx軸とy軸のラベルを記入する

chart.x_axis.title = 'time[s]'
chart.y_axis.title = 'value'

x軸とy軸の範囲を指定する

chart.x_axis.scaling.min = x軸最小
chart.x_axis.scaling.max = x軸最大
chart.y_axis.scaling.min = y軸最小
chart.y_axis.scaling.max = y軸最大

x軸とy軸のメモリの間隔を指定する

chart.x_axis.majorUnit = x軸の間隔
chart.y_axis.majorUnit = y軸の間隔

x軸とy軸のフォーマットを変更する

chart.x_axis.majorGridlines.spPr = GraphicalProperties(ln=LineProperties(solidFill= x軸の色, w=127, prstDash= プロット種類))
chart.y_axis.majorGridlines.spPr = GraphicalProperties(ln=LineProperties(solidFill= y軸の色, w=127))

プロット種類は、下記から選択可能

‘dashDot’, ‘solid’, ‘sysDashDotDot’, ‘lgDash’, ‘sysDashDot’, ‘sysDot’, ‘dot’, ‘lgDashDotDot’, ‘sysDash’, ‘lgDashDot’, ‘dash’

wは正直係数がよくわからなかった。

とりあえず127を基準に探ってみてほしい

x軸とy軸のグリッド線をオフにする

chart.x_axis.majorGridLines = None
chart.y_axis.majorGridLines = None

タイトルとx軸, y軸のラベルの書式を変える

# 肝にになるのは下記書式部分
char_properties = CharacterProperties(latin=フォント名, sz=文字サイズ*100, b=boldするか, solidFill=文字色)
# 例 : char_properties = CharacterProperties(latin=Font(typeface='Meiryo UI'), sz=1400, b=True, solidFill="000000")

paragraph_properties = ParagraphProperties(defRPr=char_properties)

# タイトルの書式を変更
chart.title.tx.rich.p[0].pPr = paragraph_properties

# x軸ラベルの書式を変更
chart.x_axis.title.tx.rich.p[0].pPr = paragraph_properties

# y軸ラベルの書式を変更
chart.y_axis.title.tx.rich.p[0].pPr = paragraph_properties

マーカーの種類変える

chart.series[0].marker.symbol = マーカーの種類

下記から選択可能

‘diamond’, ‘triangle’, ‘circle’, ‘picture’, ‘star’, ‘auto’, ‘dot’, ‘x’, ‘square’, ‘plus’, ‘dash’

マーカーのサイズを変える

# 数字を直値で入力すればOK
chart.series[0].marker.size = 8

マーカーの色合いを変える

色の選び方は、下記サイトを参考にしてみてほしい

HTML Color Codes
Get HTML color codes for your website. Color chart, color picker and color palettes.
chart.series[0].marker.graphicalProperties.solidFill = 塗りつぶしの色
chart.series[0].marker.graphicalProperties.line.solidFill = 外枠の色

ラインの色を変える

chart.series[0].graphicalProperties.line.solidFill = ラインの色

ラインを滑らかに表示する

chart.series[1].smooth = True

凡例のフォーマットを変更する

リッチテキストとして取り扱う

char_properties = CharacterProperties(latin=Font(typeface=フォント名), sz=サイズ*100, b=boldするか)
paragraph_properties = ParagraphProperties(defRPr=char_properties)
rich_text = RichText(p=[Paragraph(pPr=paragraph_properties, endParaRPr=char_properties)])
chart.legend.txPr = rich_text

凡例の置く位置を変える

x方向、y方向ともに最小値を0最大値を1として場所を相対的に指定できる。

こればかりはとりあえず値を弄ってみて、変化の具合をみながら合わせこもう

chart.legend.layout = Layout(manualLayout = ManualLayout(
        yMode='edge',
        xMode='edge',
        x=x方向の相対位置(max:1), y=y方向の相対位置(max:1),
        h=y方向大きさ, w=(x方向大きさ)
    ))

チャートの複製

ただ単に chart2 = chartだけではエラーがでる。特殊コピーが必要

chart2 = deepcopy(chart)

サンプルコード

# -*- coding: utf-8 -*-

import openpyxl
from openpyxl import Workbook, load_workbook
from openpyxl.chart import ScatterChart, LineChart, Reference, Series
from openpyxl.chart.shapes import GraphicalProperties
from openpyxl.chart.layout import Layout, ManualLayout
from openpyxl.chart.text import RichText
from openpyxl.drawing.text import Paragraph, ParagraphProperties, CharacterProperties, Font, RichTextProperties
from openpyxl.drawing.line import LineProperties
from copy import deepcopy
 

wb = load_workbook('./sample.xlsx')
ws = wb['Sheet1']
ws.title = 'summary'

chart = ScatterChart()
chart.title = "sample 散布図"
chart.style = 13
chart.x_axis.title = 'time[s]'
chart.y_axis.title = 'value'
chart.height = 15
chart.width = 25

xvalues = Reference(ws, min_col=1, min_row=2, max_row=10)
for i in range(2, 4):
    values = Reference(ws, min_col=i, min_row=1, max_row=10)
    series = Series(values, xvalues, title_from_data=True)
    chart.series.append(series)

chart.series[0].marker.symbol = "triangle"
chart.series[0].marker.size = 8
chart.series[0].marker.graphicalProperties.solidFill = "FF0000"
chart.series[0].marker.graphicalProperties.line.solidFill = "0000FF"
chart.series[0].graphicalProperties.line.solidFill = "0000FF"

chart.series[1].marker.symbol = "circle"
chart.series[1].marker.size = 8
chart.series[1].marker.graphicalProperties.solidFill = "0000FF"
chart.series[1].marker.graphicalProperties.line.solidFill = "FF0000"
chart.series[1].graphicalProperties.line.solidFill = "FF0000"
chart.series[1].smooth = True

chart.x_axis.scaling.min = 0
chart.y_axis.scaling.min = 0
chart.x_axis.scaling.max = 12
chart.y_axis.scaling.max = 10
chart.x_axis.majorUnit = 1

chart.x_axis.tickLblPos = "low"
chart.x_axis.majorGridlines.spPr = GraphicalProperties(ln=LineProperties(solidFill= "696969", w=0.01*12700, prstDash="dt"))
chart.y_axis.majorGridlines.spPr = GraphicalProperties(ln=LineProperties(solidFill= "696969", w=0.01*12700))

char_properties = CharacterProperties(latin=Font(typeface='Meiryo UI'), sz=1400, b=True, solidFill="000000")
paragraph_properties = ParagraphProperties(defRPr=char_properties)
chart.title.tx.rich.p[0].pPr = paragraph_properties
chart.x_axis.title.tx.rich.p[0].pPr = paragraph_properties
chart.y_axis.title.tx.rich.p[0].pPr = paragraph_properties

chart.x_axis.title.layout = Layout(ManualLayout(x = 0.45, y = 0.92, xMode="edge", yMode="edge"))
chart.y_axis.title.layout = Layout(ManualLayout(x = 0.02, y = 0.5, xMode="edge", yMode="edge"))


char_properties = CharacterProperties(latin=Font(typeface='Meiryo UI'), sz=800, b=False)
paragraph_properties = ParagraphProperties(defRPr=char_properties)
rich_text = RichText(p=[Paragraph(pPr=paragraph_properties, endParaRPr=char_properties)])
chart.legend.txPr = rich_text

 
chart.legend.layout = Layout(manualLayout = ManualLayout(
        yMode='edge',
        xMode='edge',
        x=0.9, y=0.1,
        h=0.1, w=0.1
    ))

ws.add_chart(chart, "A12")

chart2 = deepcopy(chart)
chart2.x_axis.scaling.min = 4
chart2.x_axis.scaling.max = 6
chart2.y_axis.scaling.min = 3
chart2.y_axis.scaling.max = 7
chart2.x_axis.majorUnit = 0.5

ws.add_chart(chart2, "A36")

wb.save('./output.xlsx') 

普段私が使う散布図のプロットは全てpythonからできるようになった。

これでエクセルでのグラフプロットに移行できる。

 

↓openpyxlの使い方まとめ↓

タイトルとURLをコピーしました