1.目的
pythonで作成した散布図をエクセルに出力するためにopenpyxlを使った。
そのとき、各プロットデータのまとまりごとでx値、y値、サンプルデータ数が異なっていて苦労したので検討したをやり方まとめる。
2.作成する散布図
ここでは例としてsklearnのirisのデータセットを散布図をエクセルに出力することを考える。
from sklearn import datasets
import pandas as pd
import matplotlib.pyplot as plt
iris = datasets.load_iris()
df = pd.DataFrame(iris.data,columns=iris.feature_names)
df['target'] = iris.target
df.loc[df['target'] == 0, 'target'] = "setosa"
df.loc[df['target'] == 1, 'target'] = "versicolor"
df.loc[df['target'] == 2, 'target'] = "virginica"
feature1 = 'sepal length (cm)'
feature2 = 'sepal width (cm)'
for t in df.target.unique():
x = df[df.target==t].loc[:,feature1]
y = df[df.target==t].loc[:,feature2]
plt.title('test graph')
plt.xlabel(feature1)
plt.ylabel(feature2)
plt.legend()
plt.show()
3.エクセルで作成
上の散布図をエクセルで作成するために以下のコードを実行。
import openpyxl
from openpyxl import Workbook
from openpyxl.chart import (
ScatterChart,
Reference,
Series,
)
wb = Workbook()
ws = wb.active
feature1 = 'sepal length (cm)' #グラフでx軸になる特徴量
feature2 = 'sepal width (cm)' #グラフでy軸になる特徴量
chart = ScatterChart() #散布図をかく
chart.title = 'test graph' #グラフタイトル
chart.style = 10 #グラフのデザイン
chart.x_axis.title = feature1 #x軸ラベル
chart.y_axis.title = feature2 #y軸ラベル
r_end = 0 #
for t in df.target.unique(): # setosa, versicolor,versicolorについてforループ処理を行う
data_t = pd.DataFrame()
data_t[''] =df[df.target==t].loc[:,feature1] # x値を抽出
data_t[t] = y = df[df.target==t].loc[:,feature2] # y値を抽出
input_data = data_t.T.reset_index().T.values.tolist()
for row in input_data : #抽出した情報をエクセルシートに貼り付け
ws.append(row)
r_start = r_end+1 # エクセルの「グラフの選択」の系列のスタート行を設定するためのパラメータ
r_end = r_start+len(input_data)-1 # エクセルの「グラフの選択」の系列のエンド行を設定するためのパラメータ
xvalues = Reference(ws, min_col=1, min_row=r_start+1, max_row=r_end ) # 系列xの値
values = Reference(ws, min_col=2, min_row=r_start, max_row=r_end ) # 系列yの値
series = Series(values, xvalues, title_from_data=True)
series.marker = openpyxl.chart.marker.Marker('circle') #マーカはサークルに設定
series.graphicalProperties.line.noFill = True #プロットのみのため線はかかない設定にする
chart.series.append(series)
ws.add_chart(chart, "E2") #グラフ貼り付けの位置(グラフの左上端)
wb.save("sample.xlsx")
これを実行すると、sample.xlsxというファイルが作成され、開くと以下のようなグラフができている。
※データの並び
・ws.append(row)
でデータをシートに書き込むと、新しいデータは下の行に追加される。
⇒列方向にデータを追加することをあきらめて、縦にデータを並べることにした。
4.参考資料
以下、参考にして勉強しました。
OpenPyXLのサイト:https://openpyxl.readthedocs.io/en/stable/index.html#
- Scatter Charts:上のコードはこのページのものを改造
- Line Charts:プロットの設定等を参照
以上