Pythonライブラリ(openpyxl)によるExcel「折れ線グラフ」の作り方とデザインレシピ【徹底解説】

スポンサーリンク
Python外部ライブラリ(openpyxl)_グラフの作成_折れ線_rev0.2 openpyxl

本記事ではMS-Office ExcelをPythonで操作するライブラリとして「openpyxl」の解説をしていきます。

Excelには多くの機能が搭載されておりますので、一記事で簡潔に解説することはできません。従いまして、大項目(機能)ごとに分けた連載記事として執筆しています。図1 連載目次と今後の予定

Part8_目次
図1 連載目次と今後の予定

前回の連載7回目の記事では、openpyxlによるグラフの作成方法の基本的な手順と種類、そして主要なクラスやオブジェクトを紹介してきました。

今回の記事からはグラフの作成の手順をサンプルコードを使ってより具体的に解説していきます。

実際のコードを追うことで、前回の【概要編】で解説した「グラフ作成における一連の流れ」や「グラフを構成するオブジェクトの階層構図」「各種属性について」といったことをより深く理解することができるでしょう。

openpyxlを使うことで、とても簡単に実用的なグラフを描画できることを実感してみてください。


この記事を読むことでopenpyxlのExcel操作に関する、次のようなことが「できる・わかる」ようになりますので最後までお付き合いください。

➀. 折れ線・棒グラフといった系列ごとに同じ項目(カテゴリ)を共有するタイプのグラフの作り方が分かる。

➁. 折れ線(LineChart)の詳細なコード解説により、「グラフ全体の構成要素の追加」や「プロットエリアの系列データ(Seriesオブジェクト)ごとの装飾」方法が分かる。

本サイトでの紹介例は一例です。また、関数などの省略可能なオプション引数などについては割愛していますので、詳細や不明点などは必要に応じて公式サイトなどを参照してください。

なお、グラフそのものの説明ではなく、Pythonプログラムでグラフを作成する際のキーポイントや特殊属性(プロパティ)について解説していきます。グラフそのももの説明は各種Excelの専門書を参考にして下さい。

スポンサーリンク

1. グラフ作成の手順

oenpyxlでグラフ作成をする手順について解説します。

折れ線、棒グラフなどの各系列によって同じ項目(X軸)を共有するようなグラフのタイプでは、複数の系列データをまとめて一括参照することができます。この場合のグラフ作成のフロー全体を体系化したのが図2になります。

Python_openpyxlによるグラフの作成フロー_系列データ一括取得_rev0.3
図2 グラフ作成の手順(系列をまとめて一括参照)

各ブックについて補足します。

➀.「Chartオブジェクトを生成する

例えば折れ線グラフであれば「LineChartクラス」という専用のクラスが用意されていますので、インポートしてオブジェクトを生成します。このChartオブジェクトがグラフ本体(フレームワーク)となります。

➁.「Chartオブジェクトにグラフの構成要素を設定する

グラフには、タイトル、凡例、軸のタイトルなどさまざまな要素により構成されます。これらをChartオブジェクトに専用の属性(プロパティ)で追加・設定していきます。

➂.「データの参照情報をReferenceオブジェクトとして定義する

グラフが参照するセル範囲を定義します。ライブラリが必要とするセル範囲は2つあって、1つ目が「項目名(カテゴリ)の列」と「系列名の行」で挟まれた個々のデータ領域です。そして2つ目が、項目名(カテゴリ)となるセル範囲です。両者は、それぞれReferenceオブジェクトとしてまとめられて参照されます。(図3)

python_Referenceオブジェクトの参照領域(データ領域_項目名領域)_rev0.2
図3 系列データと項目名(カテゴリ)の参照セル範囲(Referenceオブジェクト)

➃.「Chartオブジェクトにデータを設定する

➂で取得したデータのReferenceオブジェクトを「add_data()メソッド」でChartオブジェクトに追加します。

➄.「Chartオブジェクトに項目名(カテゴリ)を設定する

➂で取得した項目名(カテゴリ)のReferenceオブジェクトを「set_categories()メソッド」でChartオブジェクトとに追加します。

➅.「系列データごとに装飾効果を適用する

グラフの系列データはSeriesオブジェクトとして管理されています。マーカーやライン、塗り潰しなどは、個々のSeriesオブジェクトの属性にて設定していきます。

➆.「Worksheetにグラフを挿入する

最後にWorksheetオブジェクトの「add_chart()メソッド」の引数にChartオブジェクトとCellアドレスを指定してシートにグラフを挿入します。

以上がグラフ作成の手順となります、次節より具体的なコード例を交えながら詳細に解説していきます。今回は、数多くあるグラフの種類の中でも使用頻度の高い「折れ線グラフ(LineChart)」を取り上げます。

2. 折れ線グラフについて

Python_基本文法_内包表記

X軸(項目名)とY軸(値)の対となるデータをプロット、各プロット間をラインで結ぶグラフでもっとも一般的な形態のグラフです。データの参照方法は、全ての系列情報を含むデータをReferenceオブジェクトに一括にまとめます。

同じようなグラフに散布図がありますが、違いはX軸の値(カテゴリ)を各系列で共通するデータを参照する点にあります。

折れ線グラフを提供するクラスは、グラフの次元数により区別され平面(2D)はLineChartクラスと立体(3D)はLineChart3Dクラスの2種類が用意されています。

LineChart

折れ線グラフ

from openpyxl.chart import LineChart

Chartオブジェクト = LineChart(marker, smooth)

引数: marker :マーカーの有無を設定する(デフォルトNone) True:マーカー有効/False:マーカー無効

引数: smooth :滑らかなラインを設定する(デフォルトNone) True:有効/False:無効

ほか省略可能な引数は多数,全てオプショナル引数

戻り値:Chartオブジェクト


折れ線(3D)グラフ

from openpyxl.chart import LineChart3D

Chartオブジェクト =  LineChart3D(gapDepth, marker, smooth)

引数: gapDepth :床面の奥行を調整する(デフォルトNone)

引数: marker :マーカーの有無を設定する(デフォルトNone) True:マーカー有効/False:マーカー無効

引数: smooth :滑らかなラインを設定する(デフォルトNone) True:有効/False:無効

ほか省略可能な引数は多数,全てオプショナル引数

戻り値:Chartオブジェクト

また、LineChartオブジェクトがもつgrouping属性によって、グラフの形態を「“standard”(標準)」、「“stacked”(積み上げ)」,「 “percentstacked”(100%積み上げ)」の3つから選択することができます。折れ線グラフの次元とそれぞれの形態の特徴は図4のとおりですので参照してください。

折れ線グラフの種類
図4 折れ線グラフの種類

プロットエリアの構成要素には、マーカー(Markerオブジェクト)やライン(Lineオブジェクト)を持たせることができ、系列ごとにSeriesオブジェクトで管理されています。

ここまでが、折れ線グラフ(LineChartオブジェクト)の概要となります。次項より具体的なサンプルコードを示しながら作成手順を解説していきたいと思います。

3. 折れ線グラフ(平面:LineChart)のサンプルコード

それでは、次のような仕様の折れ線グラフのサンプルコードを幾つかのListに分けて順番に紹介していきます。

<サンプルコードの仕様>

4つの系列データをもつ「折れ線グラフ」とする

メインタイトルと軸のタイトルをもつものとする

プロットエリア上の各カテゴリ位置にはマーカーをつける

各系列ごとに線の種類と色を設定する

凡例をグラフの下側に配置する

3.1 折れ線グラフの概要定義

必要なクラスのインポートから、グラフ本体となるChartオブジェクト、それからグラフのタイトルや凡例などの構成要素を作っているのが次の<List1>になります。

from openpyxl import load_workbook

# グラフ作成に必要なクラスをインポート
from openpyxl.chart import LineChart, Reference, Series
from openpyxl.utils.units import pixels_to_EMU


wb = load_workbook('Graph_DataSource.xlsx') # Excelファイル(データ)の読込み
ws = wb.worksheets[0]    # Worksheetオブジェクト

# [A] グラフの構成要素の準備 --------------------------------------------------

 c1 = LineChart()   # Chartオブジェクト(折れ線グラフの本体)を取得

# グラフの大きさを調整する
c1.width = 18     # デフォルト(15cm)
c1.height = 10    # デフォルト(7cm)


# グラフのタイトルを設定(メイン、軸)
c1.title = "Line Chart"              # メインタイトル
c1.x_axis.title = 'Month'            # X軸のタイトル
c1.y_axis.title = 'Precipitation'    # Y軸のタイトル

# グラフの凡例
c1.legend.position = 'b'     # 凡例の配置位置

# グラフのスタイル
c1.style = 30               # テーマカラーの設定
c1.grouping = "standard"     # 折れ線グラフのタイプ(標準)

# <List2>へ続く

13行目では、折れ線グラフの本体となるChartオブジェクトをLineChartクラスから取得しています。これ以降はこのChartオブジェクト配下のメソッドや属性(プロパティ)を使ってグラフを構成していきます。

16・17行目 【サイズ】

グラフの大きさはデフォルトでは(17cm×7cm)で作成ますが、個別に指定する場合には、width/height属性で設定しています。

22・23行目 【タイトル】

次にグラフのタイトルの設定を行います。本タイトルはtitle属性で設定します。

X軸/Y軸のタイトルは各軸のオブジェクトに対して「title属性」で設定します。軸のオブジェクトはx_axis/y_axis属性で取得しますが、コードでは属性チェーン(属性.属性)で一度に設定しています。

26行目 【凡例】

凡例の設定となります。凡例のオブジェクトはlegend属性にて取得します。デフォルトでは凡例は自動で表示されますが、「legend属性」に“None”を設定することで非表示にすることができます。また、26行目ではさらにposition属性でプロットエリアの下側に配置するようにしています。

また、グラフ全体テーマカラーは、style属性にインデックスを設定することで簡単に設定することができます。(図5)

折れ線グラフのスタイル_簡易版_rev0.1
図5 style属性によるテーマカラーの変更

3.2 折れ線グラフの参照情報の定義

<List2>ではデータの参照元情報をChartオブジェクトに追加しています。

(<List1>の続きに<List2>を追記してください)

# [B] データの参照情報を取得する --------------------------------------------------

# データ(系列名を含めた)となるセル範囲の参照オブジェクトを取得
# 3(C)列-6(F)列、4行目-10行目を参照
data = Reference(ws, min_col=3, max_col=6, min_row=4, max_row=10)

# 項目名(カテゴリ)となる列の参照オブジェクトを取得
# 2(B)列、5行目-10行目を参照
category = Reference(ws, min_col=2, max_col=2, min_row=5, max_row=10)

# Chartオブジェクトにデータと項目を設定する
c1.add_data(data, titles_from_data=True)  # 第2引数にTrueを指定して先頭要素を系列名とする
c1.set_categories(category)                # 項目(カテゴリ)を設定

まず、5行目では系列名を含めたデータの参照元のセル範囲をReferenceオブジェクトとして定義します。(図6の赤の枠内)

そして、9行目では項目名(カテゴリ)となる列のセル範囲を同じく、Referenceオブジェクトとして定義します。(図6の紫の枠内)

折れ線グラフのセル範囲の参照情報_List2_rev0.1
図6 データの参照セル範囲(Referenceオブジェクト)

そして、12行目のadd_data()メソッドでデータ情報を、13行目のset_categories()メソッドで項目(カテゴリ)を設定します。

また、add_data()メソッドでは、引数title_from_data“True”と設定することでデータのReferenceオブジェクトの先頭要素を系列名にするようにしています。

3.3 折れ線グラフの系列の書式設定(マーカー)

<List3>では4つあるそれぞれの系列に、マーカーや線の種類・色を指定して装飾するブロックになります。(<List2>の続きに<List3>を追記してください)

系列データは、Chartオブジェクト内ではSeriesコレクション(コンテナ)として管理されているので、個々の系列データの設定をするにはコンテナから一つずつ要素(Seriesオブジェクト)を取り出して設定していく必要があります。

# [C] 各系列ごとにマーカとラインを設定する

# <系列1>のSeriesオブジェクト -----------------------------------------------------------
ser1=c1.series[0]

## マーカー設定
ser1.marker.symbol = 'circle'     # マーカーの形状(円)を選択
ser1.marker.size = 8              # マーカーの大きさを設定(整数)
ser1.marker.graphicalProperties.solidFill = 'FF0000'       # マーカーの塗り潰し色を設定
ser1.marker.graphicalProperties.line.solidFill = '0F0F0F'  # マーカーの枠線の色を設定

## のライン設定 
ser1.graphicalProperties.line.solidFill = '00AAAA'         # 線の色を設定する
ser1.graphicalProperties.line.dashStyle = "dashDot"        # 線のタイプを設定する 
ser1.graphicalProperties.line.width = pixels_to_EMU(2.5)   # 線の太さを設定する EMUsで指定する


# <系列2>のSeriesオブジェクト -----------------------------------------------------------
ser2=c1.series[1]

## マーカーの設定
ser2.marker.symbol = 'diamond'    # マーカーの形状(ひし形)を選択
ser2.marker.size = 9              # マーカーの大きさを設定(整数)
ser2.marker.graphicalProperties.solidFill = '0202F2'       # マーカーの塗り潰し色を設定
ser2.marker.graphicalProperties.line.solidFill = '00F0F'   # マーカーの枠線の色を設定

## ラインの設定
ser2.graphicalProperties.line.solidFill = 'AAAA00'         # ラインの色を設定する
ser2.graphicalProperties.line.dashStyle = "sysDashDot"     # ラインのタイプを設定する 
ser2.graphicalProperties.line.width = pixels_to_EMU(2.5)   # ラインの太さを設定する EMUsで指定する


# <系列3>のSeriesオブジェクト -----------------------------------------------------------
ser3=c1.series[2]

## マーカーの設定
ser3.marker.symbol = 'triangle'   # マーカーの形状(三角形)を選択
ser3.marker.size = 9              # マーカーの大きさを設定(整数)
ser3.marker.graphicalProperties.solidFill = '00FF11'       # マーカーの塗り潰し色を設定
ser3.marker.graphicalProperties.line.solidFill = '00F0F'   # マーカーの枠線の色を設定

## ラインの設定
ser3.graphicalProperties.line.noFill=True     # ラインを無効にする
4行目 【系列の取得】

Series属性でSeriesコレクションを取得しています。コレクションはインデックス指定で個別要素にアクセスすることができます。ここでは「0」を指定して<系列1>となるSeriesオブジェクトを取得しています。

7~10行目 【マーカーの設定】

<系列1>のマーカーに関する設定を行っています。マーカーは marker属性 でオブジェクトを取得できます。以後はさらにこのMarkerオブジェクト 配下の属性を繋いで(属性チェーン)詳細設定をしていきます。

マーカーの形状はsymbol属性、サイズは size属性、塗り潰し・枠線についてはgraphicalProperties属性を介してさらに属性を繋げていきます。

以上Markerオブジェクトの属性について整理したのが<表1>になります。

プロパティ名機能その他・関連オブジェクト
symbolプロパティマーカーの形状を設定する例(’triangle’ ,‘plus’, ‘diamond’等など)
sizeプロパティマーカーのサイズを設定する例(7.0など浮動小数点)
graphicalProperties.solidFillプロパティマーカーの塗り潰しFF0000などのRGB指定の他、ColorChoiceオブジェクトにより設定できる
graphicalProperties.line.solidFillプロパティマーカーの枠線の色FF0000などのRGB指定の他、ColorChoiceオブジェクトにより設定できる
表1 Markerオブジェクトの主な属性

「symbol属性」に指定するマーカーの形状は{‘plus’, ‘diamond’, ‘square’, ‘dash’, ‘dot’, ‘x’, ‘auto’, ‘circle’, ‘star’, ‘picture’, ‘triangle’}の中から選択します。

また、マーカの内部の塗り潰しや枠線の設定にはさらに「graphicalProperties属性」や「line属性」を繋げていきます。

Excelのマーカー設定ウィンドウと各属性の対応関係を図7に示します。

Python_Markerオブジェクト_rev0.2
図7 Markerオブジェクトの属性指定

3.4 折れ線グラフの系列の書式設定(ライン)

13~15行目 【ラインの設定】

<系列1>のラインに関する設定を行っています。ラインはSeriesオブジェクト直下の「graphicalProperties属性」に続いて line属性 と連結させてLineオブジェクトを取得します。

Lineオブジェクトにも関連する多くの属性がありますが、ここでは線の色を solidFill属性 、線の種類を dashStyle属性 、太さを width属性 で設定しています。

以上Lineオブジェクトの属性について整理したのが<表2>になります。

プロパティ名機能その他・関連オブジェクト
solidFillプロパティ線の色を設定する“00AAAA”などRGB指定の他ColorChoiceオブジェクトで設定
dashStyleプロパティ線の種類を設定する“sysDot”など規定値を指定する
widthプロパティ線の太さを設定するEMUsもしくはutilモジュールで単位変換して設定
noFillプロパティ線をなくすTrue(有効)/False(無効)
表2 Lineオブジェクトの主な属性

線の種類は「dashStyle属性」で指定しますが、組込みスタイルとして{‘sysDashDot’, ‘dashDot’, ‘sysDash’, ‘dash’, ‘dot’, ‘lgDashDotDot’, ‘lgDashDot’, ‘sysDot’, ‘sysDashDotDot’, ‘solid’, ‘lgDash’}が用意されています。

Lineオブジェクトには、図8のように、これ以外にも数多くの設定可能な項目があります。(ほとんど、デフォルト設定のままで問題ありません。)

詳細は割愛しますので、より細かい指定をしたい場合は以下の公式ドキュメントなどを参考にして下さい。(基本的な適用方法は類似しています。)

公式ドキュメント<openpyxl.drawing.line module>

https://openpyxl.readthedocs.io/en/stable/api/openpyxl.drawing.line.html#openpyxl.drawing.line.LineProperties
Lineオブジェクトの概要
図8 Lineオブジェクトの属性指定

以降、その他の系列2,3,4も同じようにSeriesオブジェクトを取得して設定を繰り返していきます。

<系列3><系列4>のライン設定だけ補足します。

LineオブジェクトにはnoFill属性があり、“True”に設定すると“ライン無し”(マーカーなし)にできます。また、Seriesオブジェクトのsmooth属性を“True”にするとプロットに対して滑らかな曲線を描画できます。なお、滑らかな曲線に対してもマーカーは設定できます。

ここまでのサンプルコードを実行した結果は図9のようになりました。

タイトルやマーカー・ラインの装飾が施されています。

Python_折れ線グラフ_平面の実行結果rev0.1
図9 Listの実行結果

4. 折れ線グラフ(立体:LineChart3D)のサンプルコード

これまで紹介した通常の平面グラフに加え、立体的(3D)な折れ線グラフにも容易に対応ができます。

3Dグラフは、<List4>のように、LineChart3Dクラス からChartオブジェクトを取得します。

<List1>の4行目と13行目を差し替えます。

# 立体折れ線グラフの ”LineChart3Dクラス" のインポート
from openpyxl.chart import LineChart3D

#--------------- 途中<List1>と同じ -----------------

# Chartオブジェクト(折れ線グラフ3Dの本体)を取得
c1 = LineChart3D()

#--------------- 途中<List1>と同じ -----------------

その他は、通常の平面グラフの作り方とほぼ同じです。ポイントを整理すると以下の通りとなります。

Check Point

・系列はSeriesオブジェクトで取得でき、個別にラインの設定(一部)を行うことができる。

・マーカーは設定することはできない。

・grouping属性による3形態(標準・積上げ、100%積上げ)を設定できる。(2D同様)

・プロットエリアに系列名が表示されるので、凡例は不要だが設定すること自体はできる。(2D同様)

次の<List5>は系列(Seriesオブジェクト)を設定している例です。

立体グラフでは、マーカーの設定はできませんが、<List5>のようにラインのエッジや平面の色と幅(厚み)のみ個別指定ができます。その他、2Dで指定できた線の種類(dashStyle属性)、滑らかな曲線(smooth属性)、ライン無し(noFill)などは設定しても反映はされません。

# <系列1>のSeriesオブジェクト -----------------------------------------------------------
ser1=c1.series[0]

## のライン設定 
ser1.graphicalProperties.solidFill = '00AAAA'         # ラインの幅の色を設定する
ser1.graphicalProperties.line.solidFill = '00AAAA'    # ラインの縁の色を設定する
ser1.graphicalProperties.line.width = pixels_to_EMU(2.5)    # ラインの太さを設定する EMUsで指定する

<List4><List5>による立体(3D)折れ線グラフの作例は以下のようになります。

立体表現と系列1のラインに個別設定がなされています。

Python_立体(3D)折れ線グラフの実行結果
図10 List5/6による立体折れ線グラフの描画

5. 折れ線グラフの種別とスタイル<補足>

ここまで折れ線グラフについて平面と立体のサンプルコードを通じて実際の手順の解説をしてきました。平面・立体に関わらず折れ線グラフ共通の種別とスタイルについてもう少し補足してみたいと思います。

5.1 折れ線グラフの形態について

図4でも示したように折れ線グラフの形態には、“標準”、“積上げ”、“100%積上げ”3つのタイプがあります。それぞれ、LineChartオブジェクトがもつgrouping属性に「“standard”」、「“stacked”」,「“percentStacked”」を設定することで対応できます。

次の<List6>を前項の<List1><List3>の間に挿入します。

# グラフの形態を設定する
# 以下の3つのオプションから一つを選択する。

# "standard" 【標準(デフォルト)】
c1.grouping = "standard"

# stacked"  【積み上げ】
c1.grouping = "stacked"

# "percentStacked" 【100%積み上げ】
c1.grouping = "percentStacked"

“standard”は先の図9と同じですので、”stacked(積上げ)”, “percentStacked(100%積上げ)”を設定した時の実行結果を以下に示します。

Python_折れ線グラフの3つの形態
図11 List6の実行結果(折れ線グラフの3つの形態)

5.2 スタイル設定について

<List1>で少し触れましたが、Chartオブジェクトには「style属性」を設定することで、Excelにあらかじめ用意されている組込みスタイルを適用することができます。このstyle属性で設定可能なテーマスタイルは全部で48種類です。

48種類すべての書式をまとめたのが次の<表3><表4>となります。「線の色」「幅」「プロットエリアの色合い」「グラフ全体の色合い」の組合せの中から選べます。

python_openpyxl_折れ線グラフのスタイル➀
<表3> スタイル設定一覧➀

図12は<表4>のスタイル一覧の中から「Style属性」4(左)、11(中央)、26(右)に設定した例です。

python_折れ線グラフのスタイル➀_描画例
図12 スタイル設定の例(style=4, 11, 26)

python_openpyxl_折れ線グラフのスタイル②
<表4> スタイル設定一覧

図13は<表2>のスタイル一覧の中から「Style属性」35(左)、42(右)に設定した例です。

python_折れ線グラフのスタイル②_描画例
図13スタイル設定の例(style=35, 42)

どれもシンプルなデザインで使いやすく、手っ取り早くグラフを装飾したい場合には便利です。

また、Seriesオブジェクトによって系列ごとに「線」や「マーカー」を設定した場合はそちらが優先されます。

6. まとめ

いかがでしたでしょうか?

Excelを操作する外部ライブラリ「openpyxl」を使用して、折れ線グラフの作成手順を実例を交えて紹介しました。

前回のクラスやオブジェクトの説明だけでは分かりずらい点もあったかもしれませんが、実際のコードを読むことでより簡単なコードで直感的に理解できるかと思います。

グラフにはこのほかにもさまざまなタイプのものがあります。

次の機会にまた紹介していけたらと思いますので、どうぞお楽しみに!

ここまでの内容をまとめておきましょう。

➀. 折れ線グラフのような系列ごとに同じ項目(カテゴリ)を共有するグラフのChartオブジェクトを生成する際の注意点は以下の2点があります。

「Referenceオブジェクト」にてデータの参照情報を複数系列をまとめて一括取得する。

Seriesオブジェクトを使って系列ごとに追加していくようなことはできない。(後から系列を追加するようなこともできない。)

➁. 系列ごとにマーカーやラインの設定をする際は、Seriesオブジェクトを使って各種属性にて設定していく。

最後までお読みいただきありがとうございました。

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