[解決!Python]Excelワークシートに散布図を作成するには(OpenPyXL)解決!Python

2種類のデータの相関を見るのには散布図が便利だ。OpenPyXLを使ってこれを作成する手順を紹介する。

» 2022年03月15日 05時00分 公開
[かわさきしんじDeep Insider編集部]

この記事は会員限定です。会員登録(無料)すると全てご覧いただけます。

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

連載目次

from openpyxl import Workbook

wb = Workbook()
ws = wb.active

values = [
    ('生徒', '数学', '物理', '英語'),
    ('A', 82, 79, 32),
    ('B', 68, 58, 48),
    ('C', 66, 84, 71),
    ('D', 75, 52, 62),
    ('E', 28, 29, 44),
    ('F', 34, 28, 61),
    ('G', 96, 62, 68),
    ('H', 46, 54, 58),
    ('I', 20, 35, 51),
    ('J', 48, 55, 33)
]

for v in values:
    ws.append(v)

wb.save('sample_chart.xlsx')

from openpyxl.chart import Reference, ScatterChart, Series

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

chart = ScatterChart()
xvalues = Reference(ws, min_col=cmin+1, min_row=rmin+1, max_row=rmax)
for idx in range(cmin+2, cmax+1):
    values = Reference(ws, min_col=idx, min_row=rmin, max_row=rmax)
    series = Series(values, xvalues, title_from_data=True)
    chart.series.append(series)

chart.title = '数学と物理/英語との相関'  # グラフタイトル
chart.x_axis.title = '数学の点数'  # 軸ラベル
chart.y_axis.title = '物理/英語の点数'
chart.anchor = 'A13'  # グラフの表示位置
chart.width = 16  # グラフのサイズ
chart.height = 8
ws.add_chart(chart)
wb.save('sample_chart.xlsx')

symbols = ['triangle', 'diamond']
colors = ['0000FF', 'FF0000']

# マーカーの設定とグラフの線の削除
# 設定可能な値:'x', 'auto', 'picture', 'star', 'diamond', 'plus', 'dot',
# 'square', 'dash', 'triangle', 'circle'
for ser, sbl, col in zip(chart.ser, symbols, colors):
    ser.marker.size = 10
    ser.marker.symbol = sbl
    ser.marker.graphicalProperties.solidFill = col  # マーカーの塗りつぶし色
    ser.marker.graphicalProperties.line.solidFill = col  # マーカーの線色
    ser.graphicalProperties.line.noFill = True  # グラフの線を削除(マーカーのみに)
wb.save('sample_chart.xlsx')


サンプルのワークシート

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

from openpyxl import Workbook

wb = Workbook()
ws = wb.active

values = [
    ('生徒', '数学', '物理', '英語'),
    ('A', 82, 79, 32),
    ('B', 68, 58, 48),
    ('C', 66, 84, 71),
    ('D', 75, 52, 62),
    ('E', 28, 29, 44),
    ('F', 34, 28, 61),
    ('G', 96, 62, 68),
    ('H', 46, 54, 58),
    ('I', 20, 35, 51),
    ('J', 48, 55, 33)
]

for v in values:
    ws.append(v)


 Excelでこれを表示したものを以下に示す。

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

散布図

 OpenPyXLを使って散布図を作成するには、openpyxl.chart.ScatterChartクラスを使用する。その手順は以下の通り。

  • ScatterChartクラスのインスタンス(グラフ)を生成する
  • グラフのタイトル、軸ラベルなどの設定を行う
  • Referenceクラスを使って、グラフのX軸の値となる範囲、グラフのY軸の値となる範囲を指定する
  • 2つのRefenceクラスのインスタンスを使って、系列データ(Seriesクラスのインスタンス)を作成する
  • 作成した系列データをグラフ(ScatterChartクラスのインスタンス)に渡す
  • マーカーの設定などを行う
  • ワークシートにグラフを挿入する

 散布図(ScatterChart)で設定できる項目としては以下がある(一部)。

属性 説明
title属性 グラフのタイトル
x_axis.title属性 X軸のラベル
y_axis.title属性 Y軸のラベル
anchor属性 ワークシート上での表示位置(左上)
width属性 グラフの横幅
height属性 グラフの高さ
ser属性 系列ごとのマーカーや線種の設定
折れ線グラフに設定可能な項目(一部)

 散布図を使うと、2種類のデータの間に何らかの関係性があるかを一目で把握できる。ここでは、上に示したワークシートで数学の点数と物理および英語の点数の間に関係があるか(数学の点がよければ物理や英語の点もよいかそうでないか)を確認してみることにする(なお、データは筆者が散布図の例を示す目的で作成したものであり、本稿の結果と実際に数学が得意なら物理や英語が得意または不得意かは関係ないことには注意しよう)。

 これにはX軸に数学の点数を取り、Y軸に物理または英語の点を取る。数学の点数と他の科目の点数との間に正の相関があれば、だいたい右上がりのグラフとなる(例えば、数学の点がよければ物理の点もよく、数学の点がよくなければ物理の点もよくない)。数学の点数と他の科目との間に相関がなければ特徴のないグラフとなる。また、数学の点数と他の科目の点数との間に負の相関があれば、だいたい右下がりのグラフとなる。

 ScatterChartクラスを使って散布図を作成するための基本となるコードを以下に示す。

from openpyxl.chart import Reference, ScatterChart, Series

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

chart = ScatterChart()
xvalues = Reference(ws, min_col=cmin+1, min_row=rmin+1, max_row=rmax)
for idx in range(cmin+2, cmax+1):
    values = Reference(ws, min_col=idx, min_row=rmin, max_row=rmax)
    series = Series(values, xvalues, title_from_data=True)
    chart.series.append(series)

chart.title = '数学と物理/英語との相関'  # グラフタイトル
chart.x_axis.title = '数学の点数'  # 軸ラベル
chart.y_axis.title = '物理/英語の点数'
chart.anchor = 'A13'  # グラフの表示位置
chart.width = 16  # グラフのサイズ
chart.height = 8
ws.add_chart(chart)


 このコードでは、Referenceクラスを使用して、X軸の値となる数学の点数が記載された範囲を変数xvaluesに指定している。次に同じくReferenceクラスを使用して、Y軸の値となる値を変数valuesに指定している。その後、変数xvaluesと変数valuesを使って系列データを表すSeriesクラスのインスタンスを作成する(このとき、系列のタイトルを自動的に設定するためにセル範囲に「物理」「英語」が含まれるようにして、Seriesクラスのインスタンス生成時に「title_from_data=True」を指定している)。そして、それをScatterClassのインスタンスに渡している(ScatterChartクラスのseries.appendメソッド)。

Copyright© Digital Advantage Corp. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。