検索
連載

[解決!Python]OpenPyXLで面グラフをExcelワークシートに作成するには解決!Python

OpenPyXLでExcelワークシートに面グラフや3D面グラフを作成したり、グラフの種類を積み上げ面グラフ/100%積み上げ面グラフに変更したりする方法を紹介する。

PC用表示 関連情報
Share
Tweet
LINE
Hatena
「解決!Python」のインデックス

連載目次

面グラフ

from openpyxl import Workbook

wb = Workbook()
ws = wb.active

values = [
    ('YEAR', 'A', 'B', 'C'),
    (2018, 750, 500, 300),
    (2019, 850, 700, 400),
    (2020, 700, 650, 500),
    (2021, 900, 800, 400)
]

for v in values:
    ws.append(v)

from openpyxl.chart import AreaChart, Reference

rmin = ws.min_row
rmax = ws.max_row
cmin = ws.min_column
cmax = ws.max_column

chart = AreaChart()
src = Reference(ws, min_col=cmin+1, min_row=rmin, max_col=cmax, max_row=rmax)
chart.add_data(src, titles_from_data=True)
cat = Reference(ws, min_col=cmin, min_row=rmin+1, max_row=rmax)  # 項目名の設定
chart.set_categories(cat)
chart.title = 'Sample Chart'  # グラフタイトル
chart.x_axis.title = 'YEAR'  # 軸ラベル
chart.y_axis.title = 'SALES'
chart.anchor = 'A7'  # グラフの表示位置
chart.width = 16  # グラフのサイズ
chart.height = 8

ws.add_chart(chart)
wb.save('sample_chart.xlsx')

# グラフのスタイルの変更
chart.grouping = 'stacked'  # 積み上げ面グラフ
chart.grouping = 'percentStacked'  # 100%積み上げ面グラフ


3D面グラフ

from openpyxl.chart import AreaChart3D

chart = AreaChart3D()
src = Reference(ws, min_col=cmin+1, min_row=rmin, max_col=cmax, max_row=rmax)
chart.add_data(src, titles_from_data=True)
cat = Reference(ws, min_col=cmin, min_row=rmin+1, max_row=rmax)  # 項目名の設定
chart.set_categories(cat)

chart.title = 'Sample Chart'  # グラフタイトル
chart.x_axis.title = 'YEAR'  # 軸ラベル
chart.y_axis.title = 'SALES'
chart.anchor = 'A24'  # グラフの表示位置
chart.width = 16  # グラフのサイズ
chart.height = 8
ws.add_chart(chart)
wb.save('sample_chart.xlsx')

# 3次元面グラフでは第3軸のラベルが凡例と同じなので凡例を削除
chart.legend = None

# 系列の順序を入れ替える
chart.ser[0], chart.ser[2] = chart.ser[2], chart.ser[0]
wb.save('sample_chart.xlsx')


サンプルのワークシート

 本稿では主に以下のコードで作成したワークシートを例に取る。

from openpyxl import Workbook

wb = Workbook()
ws = wb.active

values = [
    ('YEAR', 'A', 'B', 'C'),
    (2018, 750, 500, 300),
    (2019, 850, 700, 400),
    (2020, 700, 650, 500),
    (2021, 900, 800, 400)
]

for v in values:
    ws.append(v)


 このコードを実行してできたワークシートをExcelで表示したものが以下だ。

サンプルのワークシート
サンプルのワークシート

面グラフの作成

 OpenPyXLを使って面グラフを作成するには、openpyxl.chart.AreaChartクラスを使用する。その手順は以下の通り。

  • Referenceクラスを使って、グラフ作成の基となる範囲を指定する
  • AreaChartクラスのインスタンス(グラフ)を生成する
  • グラフのタイトル、軸ラベル、項目名などの設定を行う
  • グラフにデータ(上で作成したReferenceクラスのインスタンス)を渡す
  • ワークシートにグラフを挿入する

 面グラフ(AreaChart)で設定できる項目としては以下がある(一部)。

属性 説明
title属性 グラフのタイトル
x_axis.title属性 X軸のラベル
y_axis.title属性 Y軸のラベル
anchor属性 ワークシート上での表示位置(左上)
width属性 グラフの横幅
height属性 グラフの高さ
grouping属性 グラフの種類
style属性 グラフのスタイル
set_categoriesメソッド X軸の項目名の設定
AreaChartで設定できる項目(一部)

 以下にこれらの設定を行って、面グラフを作成する例を示す。

from openpyxl.chart import AreaChart, Reference

rmin = ws.min_row
rmax = ws.max_row
cmin = ws.min_column
cmax = ws.max_column

chart = AreaChart()
src = Reference(ws, min_col=cmin+1, min_row=rmin, max_col=cmax, max_row=rmax)
chart.add_data(src, titles_from_data=True)
cat = Reference(ws, min_col=cmin, min_row=rmin+1, max_row=rmax)  # 項目名の設定
chart.set_categories(cat)
chart.title = 'Sample Chart'  # グラフタイトル
chart.x_axis.title = 'YEAR'  # 軸ラベル
chart.y_axis.title = 'SALES'
chart.anchor = 'A7'  # グラフの表示位置
chart.width = 16  # グラフのサイズ
chart.height = 8

ws.add_chart(chart)
wb.save('sample_chart.xlsx')

AreaChartで設定可能な項目

 title属性やanchor属性など、多くの属性については上のコードを見れば、設定方法は分かるだろう(「OpenPyXLを使ってExcelワークシートに棒グラフを作成するには」でも取り上げているのでそちらも参照されたい)。

 上のコードでは、変数srcにグラフ描画の基となるセル範囲を指定している。このとき、セル範囲の一番左の列を除外している(src = Reference(ws, min_col=cmin+1, min_row=rmin, max_col=cmax, max_row=rmax))。これは一番左の列をX軸に表示する項目名(2018〜2021年)として使用するからだ。そして、変数catには今述べた一番左の列をReferenceクラスのインスタンスに指定して、それをset_categoriesメソッドに渡すようにしている。

 一方、系列や凡例に使われるA/B/Cは変数srcが参照するセル範囲に含まれている。これは、add_dataメソッドでこのセル範囲をグラフ(変数chartが参照するAreaChartオブジェクト)に追加する際に「titles_from_data=True」として、セル範囲の先頭を系列名として使用するようにしているからだ。

 上のコードで作成した面グラフを以下に示す。

作成した面グラフ
作成した面グラフ

グラフの種類を変更する

 面グラフには以下のバリエーションがある。

  • 面グラフ:系列の値をそれぞれY軸の値としてプロットする(デフォルト)
  • 積み上げ面グラフ:各系列の値を合計したものをY軸の値とし、系列ごとに色分けしてプロットする
  • 100%積み上げ面グラフ:X軸の項目ごとに各系列の値を合計したものが100%となるように、系列ごとに色分けしてプロットする

 面グラフの種類を変更するにはgrouping属性の値を'standard'(面グラフ)、'stacked'(積み上げ面グラフ)、'percentStacked'(100%積み上げ面グラフ)のいずれかに設定する。

 上のグラフを積み上げ面グラフに変更するコードを以下に示す。

chart.grouping = 'stacked'  # 積み上げ面グラフ


 これによりグラフは次のようになる。

積み上げ面グラフ
積み上げ面グラフ

 Y軸の値が各系列の値の総計となっている(例えば、2018年ならY軸の値が「750+500+300=1550」になっている)ことに注目しよう。

 100%積み上げ面グラフにするには次のようにする。

chart.grouping = 'percentStacked'  # 100%積み上げ面グラフ


 これによりグラフは次のようになる。

100%積み上げ面グラフ
100%積み上げ面グラフ

 今度はY軸の最大値が100%になり、その中で各系列の値がどの程度の割合になっているかが色を分けて示されている。

3D面グラフの作成

 面グラフを3Dのグラフとして描画することもできる。これにはopenpyxl.chart.AreaChart3Dクラスを使用する。

 先ほど例と同じデータを使って、3D面グラフを作成するコード例を以下に示す。

from openpyxl.chart import AreaChart3D

chart = AreaChart3D()
src = Reference(ws, min_col=cmin+1, min_row=rmin, max_col=cmax, max_row=rmax)
chart.add_data(src, titles_from_data=True)
cat = Reference(ws, min_col=cmin, min_row=rmin+1, max_row=rmax)  # 項目名の設定
chart.set_categories(cat)

chart.title = 'Sample Chart'  # グラフタイトル
chart.x_axis.title = 'YEAR'  # 軸ラベル
chart.y_axis.title = 'SALES'
chart.anchor = 'A24'  # グラフの表示位置
chart.width = 16  # グラフのサイズ
chart.height = 8
ws.add_chart(chart)
wb.save('sample_chart.xlsx')


 グラフの表示位置(anchor属性)を除けば、このコードは(2Dの)面グラフを作成するコードと同じだ。このコードを実行した結果を以下に示す。

3D面グラフ(下)
3D面グラフ(下)

 このようにグラフが見づらくなったときには、系列の順序を入れ替えるとよい。グラフのser属性には系列ごとにデータが格納されているので、これを入れ替えるコードを以下に示す。

chart.ser[0], chart.ser[2] = chart.ser[2], chart.ser[0]


 この例では、最初と最後の系列を入れ替えている。これによりグラフは次のようになる。

系列の順序を入れ替えた結果
系列の順序を入れ替えた結果

 系列の順序を入れ替えることで、グラフが見やすくなったことが分かるはずだ。なお、3D化により増えた軸では凡例に表示されている内容が軸ラベルとしても表示されている。凡例が不要であれば、以下のように、legend属性にNoneを代入することで凡例を削除できる。

chart.legend = None


 これによりグラフは次のようになる。

凡例を削除した結果
凡例を削除した結果

 なお、3D面グラフでもgrouping属性を使って、積み上げ面グラフや100%積み上げ面グラフにすることが可能だ(例は省略する)

「解決!Python」のインデックス

解決!Python

Copyright© Digital Advantage Corp. All Rights Reserved.

[an error occurred while processing this directive]
ページトップに戻る