DoughnutChartクラスを使って、ドーナツグラフを作成したり、そこにパーセンテージ表示を加えたり、同心円状に複数の系列のデータを表示したりする方法を紹介する。
この記事は会員限定です。会員登録(無料)すると全てご覧いただけます。
from openpyxl import Workbook
wb = Workbook()
ws = wb.active
values = [
['Product', '2020', '2021'],
['A', 4000, 4500],
['B', 3000, 2500],
['C', 2000, 1800],
['D', 1000, 1200]
]
for v in values:
ws.append(v)
wb.save('sample_chart.xlsx')
from openpyxl.chart import Reference, DoughnutChart
rmin = ws.min_row
rmax = ws.max_row
cmin = ws.min_column
cmax = ws.max_column
chart = DoughnutChart()
labels = Reference(ws, min_col=cmin, min_row=rmin+1, max_row=rmax) # 'Product'
src = Reference(ws, min_col=cmin+1, min_row=rmin, max_row=rmax) # '2020'列
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
slice = DataPoint(idx=2, explosion=10)
chart.ser[0].data_points = [slice]
wb.save('sample_chart.xlsx')
# パーセンテージの表示
from openpyxl.chart.label import DataLabel, DataLabelList
dLbls = [DataLabel(idx=idx, showPercent=True) for idx in range(rmax-rmin)]
dLbls = DataLabelList(dLbls)
chart.ser[0].dLbls = dLbls
wb.save('sample_chart.xlsx')
# パーセンテージ表示の文字色を変更する
from openpyxl.drawing.text import CharacterProperties, ParagraphProperties, Paragraph
from openpyxl.chart.text import RichText
char_props = CharacterProperties(solidFill='FFFFFF')
para_props = ParagraphProperties(defRPr=char_props)
para = Paragraph(pPr=para_props)
bodyPr = RichText(p=[para])
chart.ser[0].dLbls.textProperties = bodyPr
wb.save('sample_chart.xlsx')
# 同心円状にドーナツグラフを表示するように系列を追加
from openpyxl.chart import Series
src2 = Reference(ws, min_col=cmax, min_row=rmin, max_row=rmax) # '2021'列
series2 = Series(src2, title_from_data=True)
series2.dLbls = dLbls
series2.dLbls.textProperties = bodyPr
chart.ser.append(series2)
wb.save('sample_chart.xlsx')
slice = DataPoint(idx=2, explosion=10)
chart.ser[1].data_points = [slice]
wb.save('sample_chart.xlsx')
本稿では以下のコードで作成したワークシートを例に取る。
from openpyxl import Workbook
wb = Workbook()
ws = wb.active
values = [
['Product', '2020', '2021'],
['A', 4000, 4500],
['B', 3000, 2500],
['C', 2000, 1800],
['D', 1000, 1200]
]
for v in values:
ws.append(v)
これをExcelで表示したものを以下に示す。
OpenPyXLを使ってドーナツグラフを作成するには、openpyxl.chart.DoughnutChartクラスを使用する。ドーナツグラフは円グラフとよく似ているが、中央が空いていて、見た目がドーナツに似ている。また、複数の系列のデータを同心円状に描画することで、特定の要素の増減をビジュアルに表現できる。作成の手順は以下の通り。
ドーナツグラフ(DoughnutChart)で設定できる項目としては以下がある(一部)。
属性 | 説明 |
---|---|
title属性 | グラフのタイトル |
anchor属性 | グラフの挿入位置 |
width属性 | グラフの横幅 |
height属性 | グラフの高さ |
ser属性 | 系列ごとのマーカーや線種の設定 |
ドーナツグラフに設定可能な項目(一部) |
ドーナツグラフを作成する基本的なコード例を以下に示す。
from openpyxl.chart import Reference, DoughnutChart
rmin = ws.min_row
rmax = ws.max_row
cmin = ws.min_column
cmax = ws.max_column
chart = DoughnutChart()
labels = Reference(ws, min_col=cmin, min_row=rmin+1, max_row=rmax) # 'Product'
src = Reference(ws, min_col=cmin+1, min_row=rmin, max_row=rmax) # '2020'
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)
この例では、最初にDoughnutChartクラスのインスタンスを生成し、その後'Product'列にある'A'〜'D'を項目名としてピックアップして変数labelsに格納し、'2020'列をドーナツグラフ描画の元データとして変数srcに格納している('2021'列は後で同心円状にドーナツグラフを描く際に使用する)。そして、add_dataメソッドで変数srcをグラフにデータとして追加して、set_categoriesメソッドで変数labelsを項目名としてセットしている。その後はラベルやグラフの表示位置とサイズを設定している。
このコードを実行すると、次のようなグラフになる。
また、円グラフと同様に、ドーナツグラフの特定の要素を他の要素から切り離して、強調表示することも可能だ。これには、切り離したい要素のインデックス(0ベース)とどのくらい切り離すのかを指定して、DataPointクラスのインスタンスを生成し、それを系列の要素のdata_points属性に設定する(複数の要素を切り離したければ、インデックスと距離を指定したDataPointオブジェクトを複数用意して、それらを要素とするリストをdata_points属性に渡す)。
from openpyxl.chart.series import DataPoint
slice = DataPoint(idx=2, explosion=10) # 3つ目の要素を切り離す
chart.ser[0].data_points = [slice]
wb.save('sample_chart.xlsx')
これにより、グラフは次のようになる。
上のコードではidxに2を指定しているが、0ベースなので、これは3つ目の要素を示している。そのため、上の画像では3つ目の要素がグラフの他の要素から切り離されている。なお、この設定は同心円状にした場合には無効化される。
Copyright© Digital Advantage Corp. All Rights Reserved.