データ分析においてよく使うデータの可視化についてまとめます。自分用でもあります。
Plotlyについてはそのうち書こうと思います。ちょっと機能が多すぎてムズイので。。ただ3Dグラフで圧倒的に強いです。
使用ライブラリ
主にSeaborn、場合によってはMatplot、特別な事情でPlotly
簡単なやつから書いていきます。
Seabornを使った超簡単なグラフたち
コードを別枠で書く必要すらないやつを最初にまとめておきます。
- 折れ線グラフ → sns.lineplot
- 棒グラフ → sns.barplot
- 散布図 → sns.scatterplot
- 箱ひげ図 → sns.boxplot
- ヒストグラム → sns.histplot
などなど。
グラフによってはX軸を指定したり、Y軸を指定したり、hue=でカテゴリ別に色分けしたりできる。他にも色々引数はあるけどよくわかりません。 上記のグラフに簡単なコードで以下のことを追加できます。紹介するのは一部です。 下のグラフはIrisのがく片の長さを花の種類ごとに散布図にしたやつです。
plt.figure(figsize=(5,5)) #グラフ自体の大きさ
plt.ylim(0,10) #Y軸の幅の変更
plt.title("AAAA!!!!",fontsize=20) # タイトル追加
plt.grid() # グリッド線追加
plt.xlabel(xlabel="iiii!!!!",fontsize=50) #Xラベルの追加
plt.xticks(fontsize=20)# X軸の文字の大きさ変更
sns.scatterplot(x="Species",y="SepalLengthCm",data=dataset)
サブプロットを使ったデータ可視化の例
とりあえずどんなデータなのか見たいっていう初期段階で使ったりする。よく使うパターンは2つ。
パターン1.for文を使って一気にたくさんグラフを作るタイプ
下のコードではIrisデータセットを使用したもので、元のデータセットから特徴量を一つずつ抽出し、ターゲット(今回は花の種類)とすべての特徴量について一つずつグラフを作成してます。
最終的な出力はswarmplot(散布図の見やすい版)ですが、ここは大体なんでもいけます。
その他のグラフの要素、上からタイトル、グリッド、各ラベル、各グラフの値、凡例はグラフの見やすさとか好き嫌いに応じて変更。
最終行はレイアウトを見やすくするやつで、これをしないとグラフがつぶれがち。
import math
feature_columns=dataset.columns
fig = plt.figure(figsize=(10,10))
for i,j in enumerate(feature_columns):
plt.subplot(math.ceil(len(feature_columns)/2), 2, i+1)
plt.title(j,fontsize=20)
plt.grid()
plt.xlabel(xlabel=j,fontsize=20)
plt.ylabel(ylabel=j,fontsize=20)
plt.xticks(fontsize=12)
plt.yticks(fontsize=12)
plt.legend(loc="lower right",fontsize=15)
sns.swarmplot(x=dataset["Species"],y=dataset[j])
plt.tight_layout()
出力結果はこんな感じ、Irisとかのちゃんとしたデータならとてもきれいに。
追記:凡例がつぶれている理由はデータの名前を指定していないからだそうです。申し訳ない。
パターン2.お手本のようなsubplot活用タイプ
下のコードは全く有名でないデータで、スーパーの時系列売上データを3つの支店に分けてグラフ化したものです。
まあ3つのデータセットを用意してサブプロットで並べているだけですね。
X軸は時間、Y軸は売上平均値ですね、hueを指定することで2つのカテゴリを同じグラフに書くことができます。
一番上の行でグラフの並べ方と数を指定しているので、ここをいじると横に並べたり4つのグラフを2×2で配置したりできます。サブプロットのお手本のような使い方な気がします。
上のグラフと同様、グラフの見栄えは適宜いじってもらって。
このコードもたぶんfor文で書けるんですけど、冗長になっちゃいました。
fig,(ax1,ax2,ax3)=plt.subplots(3,1,sharey=True,figsize=(7,14))
sns.lineplot(x="Time",y="mean_Total",data=Mand_timesale,hue="weekday",ax=ax1)
ax1.legend(loc="lower right",fontsize=20)
ax1.grid()
ax1.set_xticklabels(list(range(8,21,2)),fontsize=18)
# ax1.set_yticklabels(list(range(0,800,100)),fontsize=18)
ax1.set_xlabel(xlabel="Time",fontsize=1)
ax1.set_ylabel(ylabel="Sales",fontsize=20)
ax1.set_title("Mandalay Sales",fontsize=15)
ax1.legend(bbox_to_anchor=(1.05, 1), loc='upper left', borderaxespad=0, fontsize=18)
sns.lineplot(x="Time",y="mean_Total",data=Naypy_timesale,hue="weekday",ax=ax2)
ax2.legend(loc="lower right",fontsize=20)
ax2.grid()
ax2.set_xticklabels(list(range(8,21,2)),fontsize=18)
# ax2.set_yticklabels(list(range(0,800,100)),fontsize=18)
ax2.set_xlabel(xlabel="Time",fontsize=1)
ax2.set_ylabel(ylabel="Sales",fontsize=20)
ax2.set_title("Naypyotaw Sales",fontsize=15)
ax2.legend(bbox_to_anchor=(1.05, 1), loc='upper left', borderaxespad=0, fontsize=18)
sns.lineplot(x="Time",y="mean_Total",data=Yango_timesale,hue="weekday",ax=ax3)
ax3.legend(loc="lower right",fontsize=20)
ax3.grid()
ax3.set_xticklabels(list(range(8,21,2)),fontsize=18)
# ax3.set_yticklabels(list(range(0,800,100)),fontsize=18)
ax3.set_xlabel(xlabel="Time",fontsize=1)
ax3.set_ylabel(ylabel="Sales",fontsize=20)
ax3.set_title("Yangon Sales",fontsize=15)
ax3.legend(bbox_to_anchor=(1.05, 1), loc='upper left', borderaxespad=0, fontsize=18)
出力結果はこんな感じ。マンダレー支店、ネピドー支店、ヤンゴン支店の平日・休日別時系列売上グラフとなります。
出力結果はわかりやすいんですけど、コードが長くてちょっとキモイですねー、なんとかしたい。