openpyxlを使って、普段エクセルのプロットでよく使う機能を
pythonで実施できるようになったのでまとめました!
matplotlibでグラフ化してしまうと、python未インストール者に操作しずらいと
文句を言われてしまいます。
なので会社ではエクセルプロットすることがすごく大切です!
がんがんコピペで使ってみてください!
勉強させてもらったサイト

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
マーカーの色合いを変える
色の選び方は、下記サイトを参考にしてみてほしい
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の使い方まとめ↓