[解決!Python]Excelワークシートに円グラフを作成するには(OpenPyXL):解決!Python
OpenPyXLが提供するPieChartクラスとProjectedPieChartクラスを用いて、円グラフと補助グラフ付円グラフを作成する方法を紹介する。
from openpyxl import Workbook
wb = Workbook()
ws = wb.active
values = [
['Product', 'sales'],
['A', 345678],
['B', 234567],
['C', 87654],
['D', 9876],
['E', 12345]
]
for v in values:
ws.append(v)
wb.save('sample_chart.xlsx')
from openpyxl.chart import Reference, PieChart
rmin = ws.min_row
rmax = ws.max_row
cmin = ws.min_column
cmax = ws.max_column
chart = PieChart()
labels = Reference(ws, min_col=cmin, min_row=rmin+1, max_row=rmax)
src = Reference(ws, min_col=cmax, min_row=rmin, max_row=rmax)
chart.add_data(src, titles_from_data=True)
chart.set_categories(labels)
chart.title = 'sales' # グラフタイトル
chart.anchor = 'A9' # グラフの表示位置
chart.width = 16 # グラフのサイズ
chart.height = 8
ws.add_chart(chart)
wb.save('sample_chart.xlsx')
# 円グラフから特定の構成要素を切り離して強調表示
from openpyxl.chart.series import DataPoint
slice0 = DataPoint(idx=0, explosion=10)
slice1 = DataPoint(idx=1, explosion=20)
chart.ser[0].data_points = [slice0, slice1]
wb.save('sample_chart.xlsx')
# 上記のセル範囲の値を変更
new_values = [422, 160, 30, 5, 12]
for idx, val in enumerate(new_values, 2):
ws.cell(row=idx, column=2).value = val
# 補助円グラフ付き円グラフ
from openpyxl.chart import ProjectedPieChart
chart = ProjectedPieChart()
chart.type = "pie"
chart.splitType = 'percent'
labels = Reference(ws, min_col=cmin, min_row=rmin+1, max_row=rmax)
data = Reference(ws, min_col=cmin+1, min_row=rmin, max_row=rmax)
chart.add_data(data, titles_from_data=True)
chart.set_categories(labels)
chart.anchor = 'A28'
ws.add_chart(chart)
wb.save('sample_chart.xlsx')
# 補助縦棒付き円グラフ
chart.type = 'bar'
wb.save('sample_chart.xlsx')
サンプルのワークシート
本稿では主に以下のコードで作成したワークシートを例に取る。
from openpyxl import Workbook
wb = Workbook()
ws = wb.active
values = [
['Product', 'sales'],
['A', 345678],
['B', 234567],
['C', 87654],
['D', 9876],
['E', 12345]
]
for v in values:
ws.append(v)
Excelでこれを表示したものを以下に示す。
この値は、後で以下のコードを用いて変更する(補助円グラフ付き円グラフ作成時)。
new_values = [422, 160, 30, 5, 12]
for idx, val in enumerate(new_values, 2):
ws.cell(row=idx, column=2).value = val
円グラフ
OpenPyXLを使って円グラフを作成するには、openpyxl.chart.PieChartクラスやopenpyxl.chart.ProjectedPieChartクラスを使用する。その手順は以下の通り。
- PieChartクラスまたはProjectedPieChartクラスのインスタンス(グラフ)を生成する
- Referenceクラスを使って、グラフ作成の基となる範囲を指定する
- グラフにデータ(上で作成したReferenceクラスのインスタンス)を渡す
- グラフのタイトルなどの設定を行う
- ワークシートにグラフを挿入する
円グラフ(PieChart)で設定できる項目としては以下がある(一部)。
属性 | 説明 |
---|---|
title属性 | グラフのタイトル |
anchor属性 | グラフの挿入位置 |
width属性 | グラフの横幅 |
height属性 | グラフの高さ |
ser属性 | 系列ごとのマーカーや線種の設定 |
円グラフに設定可能な項目(一部) |
PieChartクラスを使って散布図を作成するための基本となるコードを以下に示す。
from openpyxl.chart import Reference, PieChart
rmin = ws.min_row
rmax = ws.max_row
cmin = ws.min_column
cmax = ws.max_column
chart = PieChart()
labels = Reference(ws, min_col=cmin, min_row=rmin+1, max_row=rmax)
src = Reference(ws, min_col=cmax, min_row=rmin, max_row=rmax)
chart.add_data(src, titles_from_data=True)
chart.set_categories(labels)
chart.title = 'sales' # グラフタイトル
chart.anchor = 'A9' # グラフの表示位置
chart.width = 16 # グラフのサイズ
chart.height = 8
ws.add_chart(chart)
このコード例では、PieChartクラスのインスタンスを作成している。その後、変数labelsに項目名となるセル範囲を指定し、変数dataにはグラフ描画の基となるセル範囲を指定している(系列名を含む)。そして、add_dataメソッドでそれらをグラフに設定している(このときには、変数srcに指定したセル範囲に系列名が含まれていることを示すために「titles_from_data=True」を指定している。ただし、ここでは系列は「sales」だけだ)。次に、グラフのタイトルとサイズを指定してから、ワークシートにグラフを挿入している。
このコードを実行すると、次のようなグラフが描かれる。
円グラフを構成する要素を、円グラフから切り離して、その部分だけを強調するようなことも可能だ。これにはDataPointクラスを使用する。
DataPointクラスのインスタンスを生成する際に、引数idxに円グラフから切り離す部分のインデックスを(0ベース)、引数explosionにどのくらい離すかを指定する。そして、それを系列のdata_points属性にセットする。以下に例を示す。
from openpyxl.chart.series import DataPoint
slice0 = DataPoint(idx=0, explosion=10)
slice1 = DataPoint(idx=1, explosion=20)
chart.ser[0].data_points = [slice0, slice1]
この例ではDataPointクラスのインスタンスを2つ生成して、引数idxとexplosionに別々の値を指定した。そして、これらを要素とするリストをグラフの系列を格納しているオブジェクト(chart.serオブジェクト。ここでは系列は1つだけなので、その先頭要素)のdata_points属性に代入している。
これにより、グラフは次のようになる。
上の画像を見ると、ワークシートに挿入したデータの上から2行が円グラフから切り離されていること(引数idxに0と1を指定)、円グラフからの距離がそれぞれ異なること(引数explosionと10と20を指定)が分かるはずだ。
補助円グラフ付き円グラフと補助縦棒付き円グラフ
円グラフに描画される値の中で、他の値と比べて特に小さな値があると、グラフの中でそれが見づらくなることがある。こうしたときには、そうした部分を補助的な円グラフや棒グラフに抜き出して、それらの値を別途表示することも可能だ。Excelではこれらを補助円グラフ付き円グラフとか補助縦棒付き円グラフと呼んでいる。これらはProjectedPieChartクラスを使うことで作成できる。
ここでは以下のコードで、本稿冒頭で作成したグラフ描画の基になるセル範囲の値を変更しておこう。
new_values = [422, 160, 30, 5, 12]
for idx, val in enumerate(new_values, 2):
ws.cell(row=idx, column=2).value = val
3桁の数値もあるが、5や12といった数値を円グラフに描画しようとすると、それらがとても見にくくなることが予想できる。そこでまずは補助円グラフ付き円グラフを作成してみよう。以下がそのコードだ。
from openpyxl.chart import ProjectedPieChart
chart = ProjectedPieChart()
chart.type = "pie"
chart.splitType = 'percent'
labels = Reference(ws, min_col=cmin, min_row=rmin+1, max_row=rmax)
data = Reference(ws, min_col=cmin+1, min_row=rmin, max_row=rmax)
chart.add_data(data, titles_from_data=True)
chart.set_categories(labels)
chart.anchor = 'A28'
ws.add_chart(chart)
PieChartクラスではなくProjectedPieChartクラスのインスタンスを生成すること、chart.type属性に'pie'を指定して補助円グラフ付き円グラフを作成することを指定すること、chart.splitType属性に'percent'を指定して全体のパーセンテージを基に補助円グラフに抜き出すものを決定するように伝えていることが、先ほどとは異なる。
chart.type属性には'pie'か'bar'を指定可能だ。'pie'は補助円グラフ付き円グラフを作成することを、'bar'は補助縦棒付き円グラフを作成することを意味する。chart.splitType属性には'auto'/'cust'/'percent'/'pos'/'val'のいずれかを指定可能だ。補助グラフにうまく値を抜き出せないときには他の値を指定してみると、うまくいくかもしれない。
このコードを実行すると、次のようなグラフが描画される。
補助縦棒付き円グラフを作成するには、type属性にするだけだ。以下に例を示す。
chart.type = 'bar'
これにより、次のような補助縦棒付き円グラフとなる。
Copyright© Digital Advantage Corp. All Rights Reserved.