Pythonでggplot2を使って可視化する 【plotnine入門】
この記事のタイトルとURLをコピーする
執筆者
【生命医学をハックする】運営者 (@biomedicalhacks)。生命科学研究者、医師・医学博士。プロフィールはこちら

Rにはデータの可視化をするためのライブラリーであるggplot2があり、広く使われています。PythonにもMatplotlibSeaborn等の可視化ライブラリーはありますが、Pythonからでもggplot2が使えればさらに便利です。

そこでこの記事ではpythonからggplot2を使うことができるplotnineというパッケージを紹介します。

ggplot2とplotnineの文法規則

Plotnine は ggplot2 をベースに Python で実装されたライブラリーで、pipでインストールすることができます。

ggplot2のRでのコマンドは以下のようになります。

ggplot(data, aesthetics)
+ layer1()
+ layer2()

Pythonの文法規則上、このように単純に複数行に分けて書くことができないのですが、全体を () で覆えば複数行に分けて書くことができます。

(ggplot(data,aesthetics)
+ layer1()
+ layer2()
)

Plotlineの基本

それではまず架空のデータをダウンロードします。2018年の各月の最高気温と最低気温、降水量と日照時間のデータです。

import pandas as pd

data = pd.read_csv ('plotline_test.csv')
data

200807 1

最初に、各月の最高気温の折れ線グラフをggplot形式で書いてみます。

from plotnine import *

(ggplot(data, aes('Month', 'Tmax'))
  + geom_line()
)

200807 2

しかしこれだと横軸が月に対応していないですね。Rのggplot2には軸の目盛りを整序するためのscale_x_continuousがあるので、これを使っていきます。

months = data['Month']

(ggplot(data, aes('Month', 'Tmax'))
  + geom_line()
  + scale_x_continuous(breaks=months)
)

200807 3

さらにいろいろな修飾を行うことができます。例えば、横軸の月については'Jan'や'Feb'などの文字列でラベルを付け、背景についてより白っぽいLightテーマを使い、さらに折れ線グラフのデフォルトの黒い線の代わりに赤い線を引くようにしてみます。


month_labels=('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec')

(ggplot(data, aes('Month', 'Tmax'))
  + geom_line(color='red') 
  + scale_x_continuous(breaks=months,labels=month_labels) 
  + theme_light()
)

200807 4

棒グラフの作成

続けて棒グラフ版の同じようなプロットを作成してみます。棒グラフを使うためには、geom_lineの代わりにgeom_colを使います。唯一の注意点は、棒グラフの色を変更したい場合は 'fill' を指定する必要があることです。

colorといういかにもそれっぽい名前のパラメータは、棒グラフの外枠の色を変更するだけです。
(ggplot(data, aes('Month', 'Tmax'))
  + geom_col(fill='red') 
  + scale_x_continuous(breaks=months,labels=month_labels) 
  + theme_light()
)

200807 5

降水量のデータに変更し、棒グラフの色を緑にして同様に描いてみます。

(ggplot(data,aes('Month','Rain'))
  + geom_col(fill='green')
  + scale_x_continuous(breaks=months, labels=month_labels)
  + theme_light()
)

200807 10

複合グラフ

1つの軸に複数のデータを表現したいこともあります。例えば、最高気温Tmaxと最低気温Tminを同じグラフに示したいとしましょう。

まず、TmaxとTminが同じ列にあるようにデータを変換し、別の列にTmaxまたはTminというラベルを付ける必要があります。これはPandasのmelt関数を使えば簡単にできます。

temps = pd.melt(data, id_vars=['Month'], value_vars=['Tmax','Tmin'],
var_name='Temp', value_name='DegC' )
temps

200807 6

そしてこれを使って作図していきます。

(ggplot(temps,aes('Month','DegC',fill='Temp'))
  + geom_col(position='dodge')
  + scale_x_continuous(breaks=months)
  + theme_light()
)

200807 7

複数のグラフを分割して表示する

1枚のデータに複数のグラフを分割して表示したい場合があります。

まずはデータフレームを先ほどと同じくmeltしますが、今回はデモ目的のため4種類のデータ全てを1つにまとめます。

data = pd.melt(data, id_vars=['Month'], value_vars=['Tmax','Tmin','Rain','Sun'], var_name='Measure', value_name='Value' )

200807 8

複数のグラフを同時に書くには、facet_wrapレイヤーを追加し、そこにどの種類のデータなのかを示すMeasureを渡します。

デフォルトでは、facet_wrapはすべて同じ縮尺を使用します。しかし、RainとSunはそれぞれ温度が異なります。そこで、facet_wrapにスケールが「自由」であること、つまり、各ファセットが独自のスケールを持つことを指示する必要があります。

(ggplot(data, aes('Month','Value', fill='Measure'))
  + geom_col(show_legend=False)
  + scale_x_continuous(breaks=months,labels=month_labels)
  + facet_wrap('Measure', scales='free')
  + xlab('')
  + ylab('')
  + ggtitle('plotline test')
  + theme_light()
  + theme(panel_spacing=0.5, figure_size=(10,5))
)

200807 9

まとめに代えて

この記事では、Rのggplot2をPythonでも使えるという話と、代表的なグラフについてコードの例を示しました。

Rのggplot2はとても便利なパッケージですが、それがPythonでも使えるのであれば簡単にJupyter notebookやGoogle Colabで確認できますね。

関連図書

この記事に関連した内容を紹介しているサイトや本はこちらです。

plotnineの公式ドキュメント

Rにおけるグラフの書き方入門【簡単なスクリプトコピペでOK】

Google Colaboratoryでデータサイエンスを始めよう【使い方入門】

今日も【生命医学をハックする】 (@biomedicalhacks) をお読みいただきありがとうございました。当サイトの記事をもとに加筆した月2回のニュースレターも好評配信中ですので、よろしければこちらも合わせてどうぞ

人気 月間2万アクセスの当サイトから無料ニュースレターを受け取る
この記事のタイトルとURLをコピーする
生命医学の知識や進歩を無料のニュースレターで

がんをはじめとする病気やよくある症状などの医学知識、再生医療などの生命科学研究は、研究手法が大きく前進したこととコンピューターの発達なども相まって、かつてないほどの勢いで知識の整備が進んでいます。

生命医学をハックするでは、主として医師や医学生命科学研究者ではない方や、未来を担う学生さんに向けた情報発信をしています。

2週間に1回のペースで、サイトの更新情報や、それらをまとめた解説記事をニュースレターとして発行しています。メールアドレスの登録は無料で、もちろんいつでも解除することができます。

サイト名の「ハックする」には、分かってきたことを駆使し、それを応用して、病気の治療や研究などにさらに活用していこうという意味があります。

生命医学について徐々に解き明かされてきた人類の英知を受け取ってみませんか?

この記事が気に入ったら
フォローしよう

最新情報をお届けします

Twitterでも情報発信中

こちらの記事もいかがですか?
ブログランキング参加中 (クリックしていただけると励みになります)