[解決!Python]Excelワークシートにレーダーチャートを作成するには(OpenPyXL):解決!Python
OpenPyXLのRadarChartクラスを使って、Excelのワークシートにレーダーチャートを作成したり、その種類を変更したりする方法を紹介する。
from openpyxl import Workbook
wb = Workbook()
ws = wb.active
values = [
['Team', 'A', 'B', 'C'],
['Attack', 85, 70, 65],
['Defense', 72, 58, 65],
['Organize', 83, 55, 68],
['Talent', 80, 78, 55],
['Budget', 69, 80, 55]
]
for v in values:
ws.append(v)
wb.save('sample_chart.xlsx')
from openpyxl.chart import Reference, RadarChart
rmin = ws.min_row
rmax = ws.max_row
cmin = ws.min_column
cmax = ws.max_column
chart = RadarChart()
chart.type = 'standard' # 'filled', 'marker', 'standard'
labels = Reference(ws, min_col=cmin, min_row=rmin+1, max_row=rmax)
data = Reference(ws, min_col=cmin+1, max_col=cmax, min_row=rmin, max_row=rmax)
chart.add_data(data, titles_from_data=True)
chart.set_categories(labels)
chart.title = 'Team analysis'
chart.anchor = 'A10'
ws.add_chart(chart)
wb.save('sample_chart.xlsx')
# レーダーチャートの種類を変更
chart.type = 'marker'
wb.save('sample_chart.xlsx')
chart.type = 'filled'
wb.save('sample_chart.xlsx')
サンプルのワークシート
本稿では以下のコードで作成したワークシートを例に取る。
from openpyxl import Workbook
wb = Workbook()
ws = wb.active
values = [
['Team', 'A', 'B', 'C'],
['Attack', 85, 70, 65],
['Defense', 72, 58, 65],
['Organize', 83, 55, 68],
['Talent', 80, 78, 55],
['Budget', 69, 80, 55]
]
for v in values:
ws.append(v)
これは架空のチームA、B、Cの攻撃力、守備力、組織性、個人能力、予算を数値化したものだ。Aは予算が(Bと比べて)少ないことを除けば、全ての面で優れている。Bは潤沢な予算を使って能力の高い選手を獲得しているが、それがチーム全体の攻撃力や守備力につながっていないようだ。Cは少ない予算と他の2チームに比べると能力が低い選手を組織化してほどほどの成績を上げていると考えられる。
これをExcelで表示したものを以下に示す。
レーダーチャート
OpenPyXLを使ってレーダーチャートを作成するには、openpyxl.chart.RadarChartクラスを使用する。その手順は以下の通り。
- RadarChartクラスのインスタンス(グラフ)を生成する
- Referenceクラスを使って、グラフ作成の基となる範囲を指定する
- グラフにデータ(上で作成したReferenceクラスのインスタンス)を渡す
- グラフのタイトルなどの設定を行う
- ワークシートにグラフを挿入する
レーダーチャート(RadarChart)で設定できる項目としては以下がある(一部)。
属性 | 説明 |
---|---|
type属性 | レーダーチャートの種類を指定 |
title属性 | グラフのタイトル |
anchor属性 | グラフの挿入位置 |
width属性 | グラフの横幅 |
height属性 | グラフの高さ |
ser属性 | 系列ごとのマーカーや線種の設定 |
レーダーチャートに設定可能な項目(一部) |
type属性にはレーダーチャートの種類を指定する。指定可能な値は'standard'(標準のレーダーチャート)、'marker'(マーカー付きレーダーチャート)、'filled'(塗りつぶしレーダーチャート)のいずれかだ。マーカー付きレーダーチャートにするときには、各系列のmarker.symbol属性などでマーカーの形状や線色、塗りつぶし色などを指定する。
RadarChartクラスを使って散布図を作成するための基本となるコードを以下に示す。x_axis.title属性やy_axis.title属性は設定可能だが、グラフ描画では使用されないようだ。レーダーチャートなのでX軸が表示されることはなく、特に何も指定をしないとデフォルトでY軸が表示されるがあまり意味がない。
レーダーチャートを表示するコードの例を以下に示す。
from openpyxl.chart import Reference, RadarChart
rmin = ws.min_row
rmax = ws.max_row
cmin = ws.min_column
cmax = ws.max_column
chart = RadarChart()
chart.type = 'standard' # 'filled', 'marker', 'standard'
labels = Reference(ws, min_col=cmin, min_row=rmin+1, max_row=rmax)
data = Reference(ws, min_col=cmin+1, max_col=cmax, min_row=rmin, max_row=rmax)
chart.add_data(data, titles_from_data=True)
chart.set_categories(labels)
chart.title = 'Team analysis'
chart.anchor = 'A10'
ws.add_chart(chart)
このコード例では、RadarChartクラスのインスタンスを作成している。その後、変数labelsに項目名となるセル範囲を指定し、変数dataにはグラフ描画の基となるセル範囲を指定している(系列名を含む)。そして、add_dataメソッドでそれらをグラフに設定している(このときには、変数dataに指定したセル範囲に系列名が含まれていることを示すために「titles_from_data=True」を指定している。
このコードを実行すると、次のようなグラフが描かれる。
特に指定をしない限り、上の画像のグラフ中央上部にあるようにY軸が無意味に表示されてしまう。これを抑制するにはy_axis.delete属性をTrueにする。
chart.y_axis.delete = True
これによりY軸が表示されないようになる。
レーダーチャートの種類をマーカー付きにするには、type属性に'marker'を指定して、マーカーの種類や大きさなどを指定する。
chart.type = 'marker' # マーカー付きレーダーチャート
markers = ['triangle', 'diamond', 'star']
for ser, marker in zip(chart.ser, markers):
ser.marker.symbol = marker
ser.marker.size = 8
この例では、レーダーチャートのtype属性に'marker'を指定した後に、各系列のmarker.symbol属性とmarker.size属性の値を指定している。これにより、レーダーチャートに描画される折れ線の頂点にマーカーが付加されるようになる。
なお、レーダーチャートに引かれる折れ線の色は系列(この場合はchart.serの各要素)のgraphicalProperties.line.solidFill属性で、マーカーの線色と塗りつぶし色は同じく系列のmarker.graphicalProperties.line.solidFill属性とmarker.graphicalProperties.solidFill属性などで指定できる。実際のコード例は「Excelワークシートに折れ線グラフを作成するには(OpenPyXL)」を参照されたい。
また、レーダーチャートの種類を塗りつぶし付きにするには、type属性に'filled'を指定する。
chart.type = 'filled' # 塗りつぶしレーダーチャート
これにより、レーダーチャートは各色で塗りつぶされるようになる(塗りつぶし色は各系列のgraphicalProperties.solidFill属性などで指定できる)。
なお、行と列を入れ替えて表示したいこともあるかもしれない。例えば、以下は本稿冒頭のワークシートで行と列を入れ替えたものだ。
wb = Workbook()
ws = wb.active
values = [ # values = list(zip(*values))
['Team', 'Attack', 'Defense', 'Organize', 'Talent', 'Budget'],
['A', 85, 72, 83, 80, 69],
['B', 70, 58, 55, 78, 80],
['C', 65, 65, 68, 55, 55]
]
for v in values:
ws.append(v)
この場合は項目名となる範囲や、グラフ描画のもととなる範囲の指定が行志向となることと、add_dataメソッドでのデータの追加時に「from_rows=True」を指定することを忘れないようにしよう。
rmin = ws.min_row
rmax = ws.max_row
cmin = ws.min_column
cmax = ws.max_column
chart = RadarChart()
chart.type = 'standard'
# 項目名は第1行の2列目以降
labels = Reference(ws, min_col=cmin+1, max_col=cmax, min_row=rmin)
# 描画元の範囲は2行目以降の前列(A、B、Cは系列名になる)
data = Reference(ws, min_col=cmin, max_col=cmax, min_row=rmin+1, max_row=rmax)
chart.add_data(data, titles_from_data=True, from_rows=True)
chart.set_categories(labels)
chart.title = 'Team analysis'
chart.y_axis.delete = True
chart.anchor = 'A10'
ws.add_chart(chart)
Copyright© Digital Advantage Corp. All Rights Reserved.