今回は、openpyxlで主にExcelグラフの軸の設定と凡例の設定について解説します。
特に軸に関しては設定する項目が多いですが、細かい設定まで解説したいと思います。
過去の記事と今回の内容を合わせれば、通常使用するExcelのグラフの設定はほぼ出来るようになるかと思います。
他人に見せても恥ずかしくない綺麗なExcelのグラフをPythonだけで自動作成することが出来るようになります。
環境
今回使用したPythonとopenpyxlのバージョンは以下の通りです。Anacondaを使用しました。
- Python = 3.6.10
- openpyxl = 3.0.3
Excelへ書き込みとグラフの作成
前回と同じグラフを使用します。
軸の設定を変更する
軸の設定はChartオブジェクトのx_axis、y_axisプロパティで行います。
x_axis、y_axisにはNumericAxisオブジェクトがセットされていますので、NumericAxisオブジェクトのプロパティを用いて、以下の書式で設定を変更していきます。
chart.x_axis.プロパティ名 = 値
x_axisやy_axisにNumericAxisがセットされていることを知るためには、以下のようにします。
print(type(chart.x_axis))
# <class 'openpyxl.chart.axis.NumericAxis'>
openpyxlを使いこなすためには、オブジェクトのクラスを調べ、該当するクラスのマニュアルを読み込むことが必要になります。
軸の太さと色の設定
軸の太さと色を変えるにはNumericAxisオブジェクトのspPrプロパティを使用します。
spPrについては、過去の記事で解説しています。
solidFillで色の設定を行い、wで線の太さを設定しています。solidFill、wの説明も過去の記事に説明がありますので、参照してください。
from openpyxl.drawing.line import LineProperties
from openpyxl.chart.shapes import GraphicalProperties
chart.x_axis.spPr = GraphicalProperties(ln =LineProperties(solidFill="000000", w=1*12700))
色や太さ以外も変えたい場合は、LinePropertiesクラスの説明を見て、変更したい項目を引数として渡します。
グリッドラインの設定
グリッドライン の色や太さ等の設定を変更したい場合は、NumericAxisオブジェクトのmajorGridlinesプロパティを使用します。
補助目盛のグリッドラインを変更したい場合は minorGridlinesプロパティを使います。
majorGridlinesやminorGridlinesにはChartLinesオブジェクトがセットされています。ChartLinesにはspPrプロパティがあるので、これを利用します。
from openpyxl.drawing.line import LineProperties
from openpyxl.chart.shapes import GraphicalProperties
chart.x_axis.majorGridlines.spPr = GraphicalProperties(ln=LineProperties(solidFill= "FF0000", w=0.01*12700, prstDash="dot"))
#以下のようにしてもよい
chart.x_axis.majorGridlines = ChartLines(spPr = GraphicalProperties(ln=LineProperties(solidFill="FF0000", w=0.01*12700, prstDash="dot")))
グリッドラインを消したい場合は、以下のようにします。
chart.x_axis.majorGridLines = None
軸の交点の設定
軸の交点を設定したい場合は、 NumericAxisオブジェクトのcrossesAtプロパティを使用します。
chart.x_axis.crossesAt = 0
ラベル位置の設定
軸のラベル位置を変更したい場合は、 NumericAxisオブジェクトのtickLblPosプロパティを使用します。 tickLblPosには“high”、“low”、“nextTo”のいずれかを設定します
chart.x_axis.tickLblPos = "high"
上の場合は、y軸の最大値側にx軸のラベルを設置する、という意味になります。逆に”low”とした場合は、y軸の最小値側にx軸のラベルを設置するという意味です。
“nextTo”とした場合は、軸の隣にラベルを設置するという意味になります。
ラベルの表示形式の設定
ラベルの表示形式の設定を行いたい場合は、 NumericAxisオブジェクトの numFmtプロパティを使用します。numFmtに設定できる値は、こちらを参照してください。
chart.x_axis.numFmt = "0.00E+00"
ラベルのサイズやフォントの設定
ラベルのサイズやフォントの設定は結構厄介です。 NumericAxisオブジェクトのtxPrプロパティを使うのですが、txPrにセットする値の設定方法が複雑です。
とりあえず下記をコピーしてお使い下さい。
CharacterPropertiesの引数を設定することで、色やサイズ等を変更可能です。
from openpyxl.drawing.text import Paragraph, ParagraphProperties, CharacterProperties, RichTextProperties, Font
font = Font(typeface='Verdana')
size = 1400 # 14 point size
char_prop = CharacterProperties(latin=font, sz=size, b=False) # Not bold
para_prop = ParagraphProperties(defRPr=char_prop)
rich_text = RichText(p=[Paragraph(pPr=para_prop, endParaRPr=char_prop)])
chart.x_axis.txPr = rich_text
最大値/最小値の設定
軸の最大値/最小値を変更する場合は、NumericAxisオブジェクトのscalingプロパティを使います。
scalingにはScalingオブジェクトがセットされているので、Scalingオブジェクトのプロパティを使います。
最大値、最小値は、Scalingオブジェクトのmax、minを使用します。
chart.x_axis.scaling.min = 0
chart.x_axis.scaling.max = 100
これは、次のように書いてもOKです。
from openpyxl.chart.axis import Scaling
chart.x_axis.scaling = Scaling(min = 0, max = 100)
Logスケールの設定
技術系の人はLogスケールを頻繁に使うこともあるでしょう。openpyxlでも勿論Logスケールを設定することが可能です。
Logスケールを使うには、 ScalingオブジェクトのlogBaseプロパティを使用します。logBaseには底となる数値を設定します。
chart.x_axis.scaling.logBase = 10
軸の反転の設定
軸を反転させたいときは、Scalingオブジェクトのorientationプロパティを使用し、orientationには ‘maxMin’を設定します。
orientationに’minMax’を設定することもあ可能ですが、”minMax’は通常の軸の設定です。
chart.x_axis.scaling.orientation = 'maxMin'
目盛の向きの設定
目盛の向きの設定は、 NumericAxisオブジェクトのmajorTickMark、minorTickMarkプロパティを使用します。
majorTickMarkで主目盛の向きを設定し、minorTickMarkで補助目盛の向きを設定します。
majorTickMark、minorTickMarkには、’out’, ‘corss’, ‘in’のいずれかを設定することが出来ます。
chart.x_axis.majorTickMark = "in"
目盛間隔の設定
目盛の向きの設定は、 NumericAxisオブジェクトのmajorUnit、minorUnitプロパティを使用します。
majorUnitは主目盛の間隔、minorUnitは補助目盛の間隔を設定します。majorUnitやminorUnitには数値(float)を設定します
chart.x_axis.majorUnit = 10
軸ラベルの設定を変更する
軸ラベルを設定
軸ラベル(軸のタイトル)の設定は、NumericAxisオブジェクトの titleプロパティを使用します。
chart.x_axis.title = "X"
軸ラベルの位置の設定
軸ラベルの位置を変えたい場合は以下のようにします。
from openpyxl.chart.layout import Layout, ManualLayout
chart.x_axis.title.layout=Layout(ManualLayout(x = 0.5, y = 0.9, xMode="edge", yMode="edge"))
Layoutの使い方は、過去の記事に記載があるので参考にしてください。
軸ラベルのフォントの設定
軸ラベルのフォントの変更方法は、ラベルで行った方法と若干異なります。
以下のように書くと軸ラベルのフォントを変更することが出来ました。
CharacterPropertiesの引数を設定することで、色やサイズ等を変更可能です。
from openpyxl.drawing.text import Paragraph, ParagraphProperties, CharacterProperties, Font
font = Font(typeface='Verdana')
size = 1400 # 14 point size
char_prop = CharacterProperties(latin=font, sz=size, b=True, solidFill="FF0000") #
para_prop = ParagraphProperties(defRPr=char_prop)
chart.x_axis.title.tx.rich.p[0].pPr = para_prop
ラベルと同様にchart.x_axis.txPr = rich_text
でOKかと思ったのですが、どうやら、これはダメなようです。
軸ラベルの枠線と塗りつぶしの設定
ほとんど無いとは思いますが、軸ラベルの枠線の設定や塗りつぶしを行いたい場合は以下のようにします。
from openpyxl.drawing.line import LineProperties
from openpyxl.chart.shapes import GraphicalProperties
Chart.x_axis.spPr = GraphicalProperties(solidFill = "FF0000", ln =LineProperties(solidFill="000000", w=1*12700))
#以下でもOK
chart.x_axis.spPr = GraphicalProperties()
chart.x_axis.spPr.solidFill = "FF0000"
chart.x_axis.spPr.ln.solidFill="000000"
chart.x_axis.spPr.ln.w = 1*12700
凡例の設定を変更する
凡例の設定には、Chartオブジェクトのlegendプロパティを使用します。
ChartBaseクラスを見るとlegendプロパティにはLegendオブジェクトがセットされていることが分かります。
即ち、Legendオブジェクトのプロパティを使い色々な設定を行っていきます。
chart.legend.プロパティ名 = 値
凡例を消す
凡例を消したい場合は単純に以下のようにします。
chart.legend = None
凡例の位置の変更
凡例の位置を変更するには、LegendオブジェクトのlegendPosプロパティを使用します。legendPosには、 “l”, “r”, “t”, “b”, “tr “のいずれかを設定します
chart.legend.legendPos = "r"
凡例の位置を自由に変更したい場合は、Legendオブジェクトのlayoutプロパティを使用します。
同じ方法で位置を設定します。
from openpyxl.chart.layout import Layout, ManualLayout
chart.legend.layout = Layout(manualLayout = ManualLayout(
yMode='edge',
xMode='edge',
x=0.1, y=0.1,
h=0.8, w=0.8
))
凡例のサイズとフォントの設定
凡例のサイズやフォントの設定は以下のようにします。
from openpyxl.drawing.text import Paragraph, ParagraphProperties, CharacterProperties, RichTextProperties, Font
font = Font(typeface='Verdana')
size = 1400 # 14 point size
char_prop = CharacterProperties(latin=font, sz=size, b=Ture) # b=Trueでボールドにする
para_prop = ParagraphProperties(defRPr=char_prop)
rich_text = RichText(p=[Paragraph(pPr=para_prop, endParaRPr=char_prop)])
chart.legend.txPr = rich_text
凡例の枠線と塗りつぶしの設定
凡例の枠線や塗りつぶしの設定は余り使用頻度が高くないかもしれませんが、一応記載しておきます。
from openpyxl.drawing.line import LineProperties
from openpyxl.chart.shapes import GraphicalProperties
Chart.x_legend.spPr = GraphicalProperties(solidFill = "FF0000", ln =LineProperties(solidFill="000000", w=1*12700))
#以下でもOK
chart.x_legend.spPr = GraphicalProperties()
chart.x_lenged.spPr.solidFill = "FF0000"
chart.x_legend.spPr.ln.solidFill="000000"
chart.x_legend.spPr.ln.w = 1*12700
具体例
冒頭で作成したグラフの見た目を変えるために下記のコードを追記します。下記グラフで使用するGraphicalPropertiesやLinePropertiesはimportしておいてください。
(省略)
#グラフタイトル
chart.title = "aaa"
#軸ラベル(タイトル)
chart.x_axis.title = "X"
chart.y_axis.title = "Y"
#軸の色と太さの設定
chart.x_axis.spPr = GraphicalProperties(ln = LineProperties(solidFill = "000000", w = 1 * 12700))
chart.y_axis.spPr = GraphicalProperties(ln = LineProperties(solidFill = "000000", w = 1 * 12700))
#グリッドラインの太さと設定
chart.x_axis.majorGridlines.spPr = GraphicalProperties(ln = LineProperties(w = 1 * 12700, prstDash="dot"))
chart.y_axis.majorGridlines.spPr = GraphicalProperties(ln = LineProperties(w = 1 * 12700, prstDash="dot"))
#軸の交点設定
chart.x_axis.crossesAt = 4000
chart.y_axis.crossesAt = 50
#軸の最大値最小値
chart.x_axis.scaling.min = 0
chart.x_axis.scaling.max = 100
chart.y_axis.scaling = Scaling(min = 0, max = 10000)
#ラベル位置
chart.x_axis.tickLblPos = "low"
chart.y_axis.tickLblPos = "low"
#目盛の向き
chart.x_axis.majorTickMark = "in"
chart.y_axis.majorTickMark = "out"
#目盛間隔
chart.x_axis.majorUnit = 40
#軸の反転
chart.y_axis.scaling.orientation = "maxMin"
#軸ラベルの位置
chart.x_axis.title.layout = Layout(ManualLayout(x = 0.4, y = 0.95, xMode="edge", yMode="edge"))
#軸ラベルの表示形式
chart.x_axis.numFmt = "0.00"
chart.y_axis.numFmt = "0.00E+00"
#ラベルのフォント設定
font = Font(typeface='Verdana')
size = 900 # 9 point size
char_prop = CharacterProperties(latin=font, sz=size, b=False)
para_prop = ParagraphProperties(defRPr=char_prop)
rich_text = RichText(p=[Paragraph(pPr=para_prop, endParaRPr=char_prop)])
chart.x_axis.txPr = rich_text
chart.y_axis.txpr = rich_text
#軸ラベルのフォント設定
size = 1400 # 14 point size
char_prop = CharacterProperties(latin=font, sz=size, b=True, solidFill = "FF0000")
para_prop = ParagraphProperties(defRPr=char_prop)
chart.x_axis.title.tx.rich.p[0].pPr = para_prop
chart.y_axis.title.tx.rich.p[0].pPr = para_prop
#凡例の位置
chart.legend.layout = Layout(manualLayout = ManualLayout(yMode='edge',xMode='edge',x=0.8, y=0.1))
#凡例のフォント設定
size = 800 # 8 point size
char_prop = CharacterProperties(latin=font, sz=size, b=True)
para_prop = ParagraphProperties(defRPr=char_prop)
rich_text = RichText(p=[Paragraph(pPr=para_prop, endParaRPr=char_prop)])
chart.legend.txPr = rich_text
#凡例の枠線
chart.legend.spPr = GraphicalProperties()
chart.legend.spPr.ln.solidFill = "FF0000"
(省略)

全く綺麗な図ではないですが、このように見た目を変更することが出来ます。