ヒートマップは、ある値が他の2つの変数の値によってどのように変化するかを色を使って示すデータ可視化手法である。
例えば、ある都市の大気汚染が時間帯によってどのように変化するかを理解するためにヒートマップを使用することができます。
また、ヒートマップは人間の行動を観察するために使われることもあります。人々がどのようにソーシャルメディアを利用しているか、アンケートの回答が時間と共にどのように変化しているかなどを視覚化することができます。このような手法は、特に患者に自己評価アンケートを送ることが多い心理学の研究機関では、行動のパターンを調べるのに非常に強力な手段となりえます。
ここに、2人のユーザーのTwitterの使い方の違いを示す2つのヒートマップがあります。
これらのチャートはヒートマップのすべての主要な構成要素を含んでいます。基本的に、それは色のついた正方形のグリッドで、各正方形(ビン)は、水平軸と垂直軸に沿って伸びる2つの変数の値の交点を示します。
この例では、これらの変数は次のとおりです。
-
- 一日の時間
- 分
正方形は、それぞれの時間/分のビンに入るツイート数によって色分けされています。グリッドの横には、色とカウント値との関係を示す凡例があります。この場合、色が薄い(または暖かい)ほどツイートが多く、濃い(または冷たい)ほど少ないことを意味します。だから、ヒートマップという名前なのです。
ヒートマップは、大量のデータのパターンを一目で把握するために最も有効です。例えば、午前中の暗く冷たい帯は、両候補が昼前にはあまりツイートしていないことを示しています。また、2番目のユーザーは1番目のユーザーよりもはるかに頻繁にツイートしており、午前10時にはっきりとした切れ目があるのに対し、1番目のユーザーにはそのような明確な線はありません。これは、2番目のユーザーは通常午前10時までに与えられた仕事を終え、その後ソーシャルメディアをチェックし、利用するという、日中の個人的なスケジューリングに起因していると思われます。
ヒートマップは、より高度な分析を行うための良い出発点になることがよくあります。しかし、人目を引く可視化技術でもあるため、コミュニケーションのための有用なツールにもなります。
このチュートリアルでは、PythonのSeabornライブラリを使って、上のようなヒートマップを作成する方法を紹介します。
SeabornはMatplotlibの上に構築されたデータ可視化ライブラリです。Pythonの可視化ライブラリといえば、この2つがデファクト的なリーダーです。
SeabornはMatplotlibよりも高レベルのAPIを持っており、Matplotlibのプロットを人間の目に合うようにするために通常含まなければならないカスタマイズや小さなタスクの多くを自動化することができます。また、Pandasのデータ構造と密接に統合されているので、データの前処理や可視化がより簡単に行えます。また、多くの組み込みプロットがあり、便利なデフォルトや魅力的なスタイルが用意されています。
このガイドでは、3つの主要なセクションをカバーします。
- データの準備
- ヒートマップのプロット
- ベストプラクティスとヒートマップカスタマイズ
さあ、はじめましょう
Seabornでヒートマップを作成するためのデータセットを準備する。
Pandasによるサンプルデータセットの読み込み
注意: このガイドは Python 3.8, Seaborn 0.11.0, Pandas 1.1.2 を使って書かれています。
本ガイドでは、2020年のアメリカ大統領候補のうち、当時のJoe BidenとDonald Trumpの2人が、2017年1月から2020年9月の間に投稿したツイートのタイムスタンプを含むデータセットを使用します。データセットの説明と作成方法は、こちらをご覧ください。
自分や友人のツイートから独自のデータセットを作成し、ソーシャルメディアの利用習慣を比較するのも、家庭での楽しいエクササイズになるかもしれませんね。
最初の作業は、データを読み込んで、Seabornが期待する形に変換し、私たちが作業しやすいようにすることです。
データの読み込みと操作には、Pandasライブラリを使用します。
import pandas as pd
Pandasの read_csv()
関数を使って、ツイート数のデータセットを読み込みます。データセットを指すURLを渡すか、データセットをダウンロードし、ファイルを手動で参照することができます。
data_url = "https://bit.ly/3cngqgL" # or "path/to/biden_trump_tweets.csv"
df = pd.read_csv(data_url,
parse_dates=['date_utc'],
dtype={'hour_utc':int,'minute_utc':int,'id':str}
)
Headメソッドを使って
DataFrame` の最初の数行を調べて、その形状に慣れておくとよいでしょう。
df.head()
| id | username | date_utc | hour_utc | minute_utc | retweets |
| — | — | — | — | — | — | — |
| 0|815422340540547073|realDonaldTrump|2017-01-01 05:00:10+00:00|5|0|27134||||||。
| 1|815930688889352192|realDonaldTrump|2017-01-02 14:40:10+00:00|14|40|23930
| 2|815973752785793024|realDonaldTrump|2017-01-02 17:31:17+00:00|17|31|14119||||。
| 3|815989154555297792|realDonaldTrump|2017-01-02 18:32:29+00:00|18|32|3193||||。
| 4|815990335318982656|realDonaldTrump|2017-01-02 18:37:10+00:00|18|37|7337||||。
ここでは、DataFrame
の最初の5つの要素を出力しています。最初に各行のインデックス、次にツイートの id
、そのツイートをしたユーザーの username
、そして date_utc
、 hour_utc
、 minute_utc
などの時間関連の情報が表示されています。
最後に retweets
の数が表示されるので、ツイートの内容と「注目度」の興味深い関係をチェックするのに利用できます。
データをワイドフォームのデータフレームに変換する
このようなログデータは、長い(または整頓された)フォームで編成されているのが一般的です。これは、各変数の列があり、データの各行がそれらの変数の単一の観測値(特定の値)であることを意味します。ここでは、各ツイートが各変数です。各行が1つのツイートに対応し、それに関するデータを含んでいます。
しかし、概念的にはヒートマップはデータを短く(あるいは広く)整理することが必要である。そして実際、Seabornライブラリは、これまで見てきたようなヒートマップの可視化を行うために、この形式のデータを持つことを要求しているのです。
ワイドフォームのデータは、独立変数の値が行と列の見出しになり、従属変数の値はセルに含まれます。
これは基本的に、観察していないすべてのプロパティをカテゴリとして使用していることを意味します。いくつかのカテゴリーは、複数回出現することに留意してください。たとえば、元の表では、次のようなものがあります。
ユーザー名|hour_utc|minute_utc|(分単位 | ||
RealDonaldTrump|12|4|のようになります。 | ||
realDonaldTrump|13|0| です。 | ||
realDonaldTrump|12|4|| です。 |
カテゴリーの原理を使って、ある性質の出現回数を蓄積することができる。
| — | — |
| カテゴリー|出現回数
| リアル・ドナルド・トランプ|12時間|4分|2|||。
| リアル・ドナルド・トランプ|13時間|0分|1|||。
これを最終的にヒートマップに適したものに変換することができます。
| — | — | — | — | — | — |
| 時間|0|1|2|3|4|||。
| 12 | 0 | 0 | 0 | 0 | 2 |
| 13 | 1 | 0 | 0 | 0 | 0 |
ここでは、行として時間をユニークな値として、また列として分も持っています。セル内の各値は、その時間におけるツイートの発生数です。例えば、ここでは、12:04に2ツイート、13:01に1ツイートが確認できます。この方法では、24行(24時間)、60列しかありません。この見開きを視覚的に想像すると、本質的には数字によるヒートマップと言えますが。
この例では、1日のさまざまな時間帯に候補者がどのようにツイートするかについて、何らかのパターンがあるかどうかを理解したいと思います。そのための1つの方法は、1日の各時間と1時間の各分間に作成されたツイートを数えることです。
技術的には、2880のカテゴリーがあります。hour_utc、
minute_utc、
username`の組み合わせがそれぞれ別のカテゴリとなり、それぞれのツイートの発生回数を数えます。
この集計はPandasを使えば簡単にできます。作成された時間と分は、 hour_utc
と minute_utc
というカラムで利用できます。Pandasの groupby()
関数を使って、 username
, hour_utc
, minute_utc
の組み合わせごとに、すべてのツイートを集めることができます。
g = df.groupby(['hour_utc','minute_utc','username'])
これは、hour_utc
, minute_utc
, username
の値が同じ行だけが、同じカテゴリの出現とみなすことができることを意味します。
あとは nunique()
関数を適用して、一意な id
の数を数えることで、各グループのツイート数を数えることができます。この方法は、事前に適切にクリーニングされていないデータの中に潜む、重複するツイートを二重にカウントすることを避けることができます。
tweet_cnt = g.id.nunique()
これでヒートマップを作成するために必要なカウントを含むPandasシリーズが得られます。
tweet_cnt.head()
hour_utc minute_utc username
0 0 JoeBiden 26
realDonaldTrump 6
1 JoeBiden 16
realDonaldTrump 11
2 JoeBiden 6
Name: id, dtype: int64
これを Seaborn が必要とする広い形式の DataFrame
に変換するために、Pandas の pivot()
関数を使用することができます。
この例では、一度に一人のユーザーを取り上げ、それぞれのヒートマップを別々にプロットするのが最も簡単でしょう。これを1つの図にすることもできますし、別々の図にすることもできます。
Pandasの loc[]
アクセサを使用して、1人のユーザーのツイート数を選択し、次に pivot()
関数を適用します。これは、指定されたインデックスやカラムからユニークな値を使用して、結果の DataFrame
の軸を形成します。ここでは、時間軸と分単位でピボットを行い、結果的に DataFrame
が広範な形になるようにします。
jb_tweet_cnt = tweet_cnt.loc[:,:,'JoeBiden'].reset_index().pivot(index='hour_utc', columns='minute_utc', values='id')
次に、出来上がった DataFrame
の一部分を覗いてみましょう。
jb_tweet_cnt.iloc[:10,:9]
| 分単位|0|1|2|3|4|5|6|7|8|………………………………
| — | — | — | — | — | — | — | — | — | — |
| hour_utc
| 0 | 26.0 | 16.0 | 6.0 | 7.0 | 4.0 | 24.0 | 2.0 | 2.0 | 9.0 |
| 1 | 24.0 | 7.0 | 5.0 | 6.0 | 4.0 | 19.0 | 1.0 | 2.0 | 6.0 |
| 2|3.0|3.0|NaN|5.0|1.0|4.0|8.0|NaN||||||。
| 3 | 3.0 | 3.0 | 3.0 | 4.0 | 5.0 | 1.0 | 3.0 | 5.0 | 4.0 |
| 4 | 1.0 | 1.0 | 2.0 | NaN | NaN | 1.0 | 1.0 | 1.0 | 1.0
| 5|1.0|2.0|NaN|NaN|1.0|NaN|NaN|NaN|NaN|NaN|NaN
| 6|NaN|NaN|NaN|NaN|NaN|NaN|NaN|NaN|NaN|NaN|NaN|NaN|NaN|NaN|NaN|NaN
| 10 | 7.0 | 2.0 | 1.0 | NaN|NaN|NaN|NaN|NaN|NaN|NaN|NaN|NaN|NaN
| 11|2.0|5.0|NaN|NaN|NaN|NaN|NaN|NaN|NaN|NaN|NaN|NaN|NaN|NaN|NaN|NaN
| 12|4.0|NaN|1.0|NaN|1.0|NaN|NaN|||。
欠測値への対応
変換されたデータには欠損値が含まれていることが上記でわかりました。ある分・時間の組み合わせでツイートがなかった場合、 pivot()
関数は DataFrame
に Not-a-Number (NaN
) 値を挿入します。
さらに、pivot()
は、特定の時間(または分)にツイートが全くなかった場合、行(または列)を作成しません。
7,
8,
9` の時間帯がない場合は、上記を参照してください。
これは、データの前処理をするときによく起こることです。データが欠落していたり、変な型や項目(バリデーションが行われていない)であったりなど。
Seabornはこのような欠損データをうまく処理することができ、時間7、8、9をスキップして欠損データなしでプロットします。しかし、欠損値を埋めれば、ヒートマップはより一貫性を持ち、解釈しやすくなります。このケースでは、欠損値は実際にはゼロのカウントであることが分かっています。
すでに挿入されたNaN
を埋めるには、fillna()
を次のように使用します。
jb_tweet_cnt.fillna(0, inplace=True)
ヒートマップで、すべての時間と分の組み合わせが表示されていることを確認します。
# Ensure all hours in table
jb_tweet_cnt = jb_tweet_cnt.reindex(range(0,24), axis=0, fill_value=0)
# Ensure all minutes in table
jb_tweet_cnt = jb_tweet_cnt.reindex(range(0,60), axis=1, fill_value=0).astype(int)
素晴らしい。他の候補のツイートについても同じステップを繰り返して、データの準備を完了させましょう。
dt_tweet_cnt = tweet_cnt.loc[:,:,'realDonaldTrump'].reset_index().pivot(index='hour_utc', columns='minute_utc', values='id')
dt_tweet_cnt.fillna(0, inplace=True)
dt_tweet_cnt = dt_tweet_cnt.reindex(range(0,24), axis=0, fill_value=0)
dt_tweet_cnt = dt_tweet_cnt.reindex(range(0,60), axis=1, fill_value=0).astype(int)
Seabornを使用した基本的なヒートマップの作成
データの準備ができたので、Seabornを使って簡単にヒートマップを作図することができます。まず、Seabornのライブラリがインポートされていることを確認します。
import seaborn as sns
import matplotlib.pyplot as plt
また、SeabornはMatplotlibのPyPlotをエンジンとして利用しているので、MatplotlibのPyPlotモジュールもインポートします。Seabornの適切な関数でプロットした後、実際にプロットを表示するために plt.show()
を常に呼び出します。
さて、Seabornの常として、データのプロットは準備した DataFrame
を使いたい関数に渡すだけでよいのです。具体的には、heatmap()
関数を使用します。
トランプのTwitterでの活動を簡単なヒートマップでプロットしてみましょう。
sns.heatmap(dt_tweet_cnt)
plt.show()
そしてBidenのものです。
sns.heatmap(jb_tweet_cnt)
plt.show()
Seabornのデフォルト設定で作成されたヒートマップはすぐに使用できる。ヒートマップは冒頭のプロットと同じパターンを示しているが、もう少しぎこちなく、小さく、軸のラベルが奇妙な頻度で表示される。
それはさておき、これらのパターンを見ることができるのは、Seabornが heatmap()
関数を呼び出すだけで、多くの仕事を自動的にこなしてくれるからである。
-
- カラーパレットとスケールを適切に選択した
-
- 色とその値を関連付ける凡例を作成した
- 軸のラベル付け
これらのデフォルトは、趣味やデータサイエンティストとしての目的や最初の検討には十分かもしれません。しかし、本当に効果的なヒートマップを作成するためには、オーディエンスのニーズに合わせて表示をカスタマイズする必要があることがよくあります。
ここでは、Seabornヒートマップをカスタマイズして、ガイドの冒頭で見たようなヒートマップを作成する方法を見ていきましょう。
Seabornヒートマップをカスタマイズする方法
カラーを効果的に使う
ヒートマップの特徴は、基本的な量の大きさを表すために色を使用することです。
Seaborn がヒートマップの描画に使用する色は、オプションの cmap
(colormap) パラメータを指定することで簡単に変更することができます。例えば、'mako'
カラーパレットに切り替えるには、以下のようにする。
sns.heatmap(dt_tweet_cnt, cmap="mako")
plt.show()
Seabornには多くの組み込みパレットが用意されていますが、データや目的に合ったパレットを選択するよう注意してください。
私たちのような数値データを表示するヒートマップでは、デフォルトの 'rocket'
や 'mako'
のような連続したパレットを選択するのがよいでしょう。これは、これらのパレットの色が知覚的に均一になるように選択されているためです。つまり、私たちが目で見る2つの色の差は、基本的な値の差に比例するのです。
その結果、地図をちらっと見るだけで、データの値の分布をすぐに感じ取ることができるのです。
逆の例として、知覚的に均一なパレットの利点と、不適切なパレット選択の落とし穴を示します。以下は、同じヒートマップをtab10
パレットで描いたものです。
sns.heatmap(dt_tweet_cnt, cmap="tab10")
plt.show()
このパレットはこの例では不適切な選択です。なぜなら、異なる色間の関係を理解するために本当に苦労しなければならないからです。以前は明白だったパターンがほとんど見えなくなってしまったのです!
これは、tab10
パレットが色相の変化を利用して、カテゴリー間の区別を容易にしているためです。ヒートマップの値がカテゴリカルである場合には、良い選択かもしれません。
もし、データの低い値と高い値の両方に興味がある場合は、両極端を強調する一様なスキームである coolwarm
や icefire
のような発散パレットを使用することを検討するとよいでしょう。
カラーパレットの選択に関する詳しい情報は、Seabornのドキュメントに有用なガイダンスがあります。
外れ値による歪みの抑制
データ中の外れ値は、ヒートマップをプロットする際に問題を引き起こす可能性があります。Seabornのデフォルトでは、カラースケールの境界はデータ内の最小値と最大値に設定されています。
つまり、データの値が極端に大きい(または小さい)場合、詳細が不明瞭になる可能性があります。極端な異常値であればあるほど、均一なカラーリングのステップから遠ざかります。これがどのような効果をもたらすかは、カラーマップの違いで見てきました。
例えば、1分間に400回のツイートが発生するような極端な異常値を追加した場合、その異常値1つで色の広がりが変化し、大きく歪んでしまうのです。
極端な値をデータセットから削除せずに処理する一つの方法として、オプションで robust
パラメータを使用することができます。robustを
True` に設定すると、Seaborn はカラースケールの境界を、最大値と最小値ではなく、データの 2 番目と 98 番目のパーセンタイル値に設定します。これにより、ほとんどの場合、色の広がりがより使いやすい状態に正規化されます。
この例では、出現率/色の広がりが、以前の「0…40」に対して、「0…16」になったことに注意してください。これは理想的ではありませんが、極端な値に対して迅速かつ簡単に修正することができます。
右の例が示すように、これはディテールを取り戻すことができます。カラースケールの境界より高い値や低い値は、スケールの端の色にクリップされます。
パラメータ vmin
と vmax
の値を設定することで、カラースケールの境界を手動で設定することも可能です。この機能は、2つのヒートマップを並べて表示し、それぞれのヒートマップのカラースケールを同じにしたい場合に非常に有効です。
sns.heatmap(tmp, vmin=0, vmax=40)
plt.show()
構成 軸の並べ替えで関係性を表面化
この例では、ヒートマップの軸である「時間」と「分」は、自然な順序で並んでいます。これらは連続値ではなく離散値であり、データのパターンを表面化するために並べ替えることができることに注意することが重要である。
例えば、分単位を通常の昇順にする代わりに、ツイート数が最も多い分単位で並べることができます。
これにより、ツイート数データの新たな表現が可能になります。最初のヒートマップから、バイデンは4分の1秒(毎時30分、45分、0分、15分)を好んでツイートしていることがわかります。これは、ある個人がテレビのボリュームを5刻みに設定したり、多くの人があるタスクを始めるのに「タイミングを待つ」傾向があるのと同じで、通常は丸数字か4分の1秒に設定しています。
一方、2つ目のヒートマップでは、有利な分がないように見えます。1時間のすべての分において、かなり一貫した広がりがあり、観察できるパターンは多くありません。
他の文脈では、ヒートマップの軸を構成するカテゴリ変数の慎重な順序付けおよび/またはグループ化は、データのパターンを強調し、グラフの情報密度を高めるために有用です。
付加価値アノテーション
ヒートマップの欠点は、値を直接比較することが困難なことである。棒グラフや折れ線グラフの方がはるかに簡単な方法です。
しかし、ヒートマップにアノテーションを追加することで、この問題を緩和することができます。Seabornでは、以下のように annot
パラメータを True
に設定することで、簡単に行うことができます。
sns.heatmap(jb_tweet_cnt.iloc[14:23,25:35], annot=True)
plt.show()
データをより小さく切り出して、いくつかのビンを表示したり比較したりしやすくしました。ここでは、各ビンに基本的な値が注釈されているので、比較するのが非常に簡単になりました。折れ線グラフや棒グラフのように自然で直感的ではありませんが、それでもこれは便利です。
これらの値をヒートマップ全体にプロットすることは、数字が小さすぎて読みにくいので、現実的ではありません。
妥協案としては、特定の興味深い値のみに注釈を追加するのが有効かもしれません。次の例では、最大値に対してのみアノテーションを追加してみましょう。
これは、Seabornの heatmap()
関数に annot
パラメータで渡すことができるアノテーションラベルのセットを作成することで実現できます。また、annot_kws
パラメータを使用すると、使用するフォントの大きさなど、ラベルの側面を制御することができます。
# Create data labels, using blank string if under threshold value
M = jb_tweet_cnt.iloc[14:23,25:35].values.max()
labels = jb_tweet_cnt.iloc[14:23,25:35].applymap(lambda v: str(v) if v == M else '')
# Pass the labels to heatmap function
sns.heatmap(jb_tweet_cnt.iloc[14:23,25:35], annot=labels, annot_kws={'fontsize':16}, fmt='')
plt.show()
カスタムラベルセットを定義する際に、創造力を発揮することができます。唯一の制約は、ラベルに渡すデータは、プロットするデータと同じサイズでなければならないことです。また、ラベルが文字列の場合、Seaborn がラベルを数値として解釈しないように fmt=''
パラメータを渡さなければなりません。
グリッド線と四角形
ヒートマップが離散的な量のビンに基づいていることを視聴者に思い出させるのに役立つことがあります。データセットによっては、2つのビンの間の色が非常に似ていて、グラデーションのような質感になり、特定の値を見分けるのが難しくなることがあります。パラメータ linewidth
と linecolor
を使用すると、ヒートマップにグリッドラインを追加することができます。
同様に、 square
パラメータを使用すると、正方形のアスペクト比を強制的に true にすることができます。ビンに四角形を使用する必要がないことを覚えておいてください。
各ビンの間に細い白線を追加して、それらが別々のエントリであることを強調してみましょう。
sns.heatmap(jb_tweet_cnt.iloc[14:23,25:35], linewidth=1, linecolor='w', square=True)
plt.show()
これらの各ケースにおいて、これらの美的な変更が視覚化の目的を促進するかどうかは、あなたの判断次第です。
Seabornのカテゴリー別ヒートマップ
数値データをカテゴリに分類してヒートマップを簡略化することが有効な場合があります。例えば、ツイート数のデータを 0..40
のような数値範囲ではなく、high'
, 'medium'
, 'low'
の3つのカテゴリにバケット化することができます。
残念ながら、この記事を書いている時点では、Seabornにはこのようなカテゴリデータに対してヒートマップを作成する機能が組み込まれていません。このコードでは、パレットとカラーバーを少し工夫することで、ヒートマップを “偽造 “できることを示しています。
ただし、このような機能を内蔵している他の可視化パッケージの利点を検討する必要があります。
Seabornの基盤エンジンであるMatplotlibには、低レベルのカスタマイズオプションがたくさんあり、我々はそれにフルアクセスできるので、その助けを借りることにします。ここでは、右側の凡例を「ハック」して、好きな値を表示できるようにします。
import matplotlib.pyplot as plt
fig,ax = plt.subplots(1,1,figsize=(18,8))
my_colors=[(0.2,0.3,0.3),(0.4,0.5,0.4),(0.1,0.7,0),(0.1,0.7,0)]
sns.heatmap(dt_tweet_cnt, cmap=my_colors, square=True, linewidth=0.1, linecolor=(0.1,0.2,0.2), ax=ax)
colorbar = ax.collections[0].colorbar
M=dt_tweet_cnt.max().max()
colorbar.set_ticks([1/8*M,3/8*M,6/8*M])
colorbar.set_ticklabels(['low','med','high'])
plt.show()
ヒートマップのプレゼンテーションの準備
ヒートマップの仕上げをするための最後のステップをいくつか紹介します。
Seabornのコンテキストを使用して外観を制御します。
set_context()` 関数は、全体のスタイルを変えずにプロットの要素のいくつかを制御する便利な方法を提供します。例えば、これはフォントのサイズやファミリーをカスタマイズするのに便利な方法です。
いくつかのプリセットコンテキストが利用可能です。
sns.set_context("notebook", font_scale=1.75, rc={"lines.linewidth": 2.5, 'font.family':'Helvetica'})
ヒートマップのレイアウトを制御するためのサブプロットの使用 #### ヒートマップのレイアウトを制御するためのサブプロットの使用
ツイート数のヒートマップを作成する最後のステップは、2つのプロットを1つの図の中に隣り合わせに配置して、両者を簡単に比較できるようにすることです。
Seabornではヒートマップのレイアウトを制御するために、 matplotlib.pyplot
の subplot()
機能を使用することができます。これにより、最終的なグラフィックを最大限にコントロールすることができ、画像のエクスポートも簡単に行うことができます。
Matplotlibを使ったサブプロットの作成は、その形状を定義するのと同じくらい簡単です(この例では、1列に2つのサブプロット)。
import matplotlib.pyplot as plt
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(12,12))
sns.heatmap(jb_tweet_cnt, ax=ax1)
sns.heatmap(dt_tweet_cnt, ax=ax2)
plt.show()
これは本質的には、最初に見たスタイリングに欠けていますが、そうです。このガイドで見てきた多くのカスタマイズを組み合わせて、最終的なプロットを作成し、共有するために .png
としてエクスポートしてみましょう。
import matplotlib.pyplot as plt
fig, ax = plt.subplots(2, 1, figsize=(24,12))
for i,d in enumerate([jb_tweet_cnt,dt_tweet_cnt]):
labels = d.applymap(lambda v: str(v) if v == d.values.max() else '')
sns.heatmap(d,
cmap="viridis", # Choose a squential colormap
annot=jb_labels, # Label the maximum value
annot_kws={'fontsize':11}, # Reduce size of label to fit
fmt='', # Interpret labels as strings
square=True, # Force square cells
vmax=40, # Ensure same
vmin=0, # color scale
linewidth=0.01, # Add gridlines
linecolor="#222",# Adjust gridline color
ax=ax[i], # Arrange in subplot
)
ax[0].set_title('@JoeBiden')
ax[1].set_title('@realDonaldTrump')
ax[0].set_ylabel('Hour of Day')
ax[1].set_ylabel('Hour of Day')
ax[0].set_xlabel('')
ax[1].set_xlabel('Minute of Hour')
plt.tight_layout()
plt.savefig('final.png', dpi=120)
結論
このガイドでは、ヒートマップと、PythonとSeaborn可視化ライブラリを使ったヒートマップの作成方法について見てきました。
ヒートマップの強みは、色を使って情報を伝えること、言い換えれば、誰でも簡単に大まかなパターンを一目で分かるようにすることです。
そのためには、カラーパレットとスケールを慎重に選択する必要があることを見てきました。また、Seabornのヒートマップには、グラフの特定の部分を強調するために、さまざまなカスタマイズが可能であることも見てきた。注釈、グループ化、カテゴリー軸の順序、レイアウトなどです。
データビジュアライザーの側では、可視化の状況に最も適したカスタマイズを選択するために、常に編集上の判断が要求されます。
ヒートマップには、放射状ヒートマップ、モザイクプロット、マトリクスチャートなど、多くのバリエーションがあり、研究することができます。