Chapter 10

データを強調する

mimitako
mimitako
2022.10.10に更新

データの強調もひとつのビジュアライゼーション

何か特別な状態であることをアピールするとき、強調させる工夫をします。例えば文字列であれば太文字、文字サイズを大きくする、色を変えるなどの手段を取ります。

グラフでも同じように、特に強調したいデータは色を変更することでその存在をアピールさせます。

この項目ではグラフの強調方法について述べていきます。

グレーを基準に作成する

グラフを作成する場合、とりあえず標準で出力させようとすると思いますが、今回はグレーを基準として用います。表示する必要がないときは削除をしますが、過去からの状況変化を示す必要がある場合はグレーアウトして残しておきます。

本当に必要な情報だけをピックアップすることで、”一目で見るべき場所がわかる”状態にできます。

Barplot の場合

まず Barplot のデータを見てましょう。データはシンプルにしたいので、次のように定義したものを利用します。

bar_data = {"A":range(1,11), "B":[1, 2, 3, 5, 8, 10, 15, 40, 70, 30]}
df_bar = pd.DataFrame(bar_data)

これを Barplot で表示すると次のようになります。

fig, ax = plt.subplots(1,1,dpi = 300)
ax = sns.barplot(data=df_bar, x = "A", y = "B", color="lightgray")

この状態ではあまり有り難みがありませんね。今回、A が 9->10 に変わるとき B が大きく下がりました。これについて説明するときに強調を付与したいと思います。

# 色をリストで指定する。
colors = []
for c in range(0,len(df_bar)):
  colors.append("lightgray")
colors[8] = "#D86E55"
colors[9] = "#55BFD8"

# 色のリストはpaletteで指定できます。
fig, ax = plt.subplots(1,1,dpi = 300)
ax = sns.barplot(data=df_bar, x = "A", y = "B", palette=colors)

このように単調だったグラフも見るべき場所が明らかとなりました。

さらに単純化する

科学技術のグラフである場合、枠線や目盛線などが必要となります。しかし、経営資料判断などの資料においてはそれらの情報はノイズでしかなく、不要な情報となります。

そこで、簡略化した例をひとつ示します。

その例がこちらです。y 軸の目盛線を削除し、必要な情報をラベルという形で付与しました。また、全てに対してラベルを付与するのではなく、前後関係が重要な部位に限って示しています。

y 軸の情報が何を示すかという点は、プレゼンテーションで示されますが、タイトルからもそれがひと目で分かります。したがって、y 軸の情報が消えても問題となりません。

これを達成するためのコードはこちらです。

# 色をリストで指定する。
colors = []
for c in range(0,len(df_bar)):
  colors.append("lightgray")
colors[8] = "#D86E55"
colors[9] = "#55BFD8"

# 色のリストはpaletteで指定できます。
fig, ax = plt.subplots(1,1,dpi = 300)
ax = sns.barplot(data=df_bar, x = "A", y = "B",palette=colors)

# ラベルの付与
for index, p in enumerate(ax.patches):
  # 今回はindexが7以上のデータにラベルを付与する。
  if index > 6:
    ax.annotate(format(p.get_height(), '.0f'),
      (p.get_x() + p.get_width() / 2., p.get_height()),
      ha = 'center', va = 'center',
      xytext = (0, 9),
      textcoords = 'offset points')

# 枠線の削除/残す
ax.spines['right'].set_visible(False)
ax.spines['top'].set_visible(False)
ax.spines['bottom'].set_visible(True)
ax.spines['left'].set_visible(False)

# 軸ラベルの削除/残す
ax.tick_params(
  labelbottom=True,
  labelleft=False,
  labelright=False,
  labeltop=False)

# 目盛線の削除/残す
ax.tick_params(
  bottom=True,
  left=False,
  right=False,
  top=False)

# y軸ラベルの削除、タイトルの設定
ax.set(ylabel = "",title="Number of Bugs")

scatterplot で強調する

散布図の場合、あまり強調する必要がないと考えられているかもしれませんが、意外と効果的だったりします。Iris のデータセットを用いて見てみましょう。

標準だと色が多い

seaborn、最初に使い始めたときは簡単に記述できて、色もきれいで美しいと思っていましたが、現在はうるさいなと感じるようになってきました。結局自動で色が割り付けられた場合に、どの色がどの程度重要なのかはっきりしていないためこのようなことが起こります。

ということで、まずは色を消しましょう。また、プロットの点の形も種類ごとに変えてわかりやすくします。

fig, ax = plt.subplots(1,1,dpi = 300)
ax = sns.scatterplot(
  data = iris_data,
  x = "sepal_width",
  y = "sepal_length",
  hue = "species",
  style = "species",  #点の種類をhueに合わせて指定
  palette= "binary" #色の指定
  )

このままだといつも通りですし、色がない分何が何だかという感じですね。

強調したい点に色をつける

これはBarplotと同じように各点に対して色を指定します。

# 色をリストで指定する。
colors = []
for c in range(0,len(iris_data)):
  if iris_data.loc[c].species == "setosa":
    colors.append("#55BFD8")
  else:
    colors.append("lightgray")

# グラフを描画します。
fig, ax = plt.subplots(1,1,dpi = 300)
ax = sns.scatterplot(
  data = iris_data, 
  x = "sepal_width", 
  y = "sepal_length", 
  style = "species", # 点の形は区別したいためhueではなくstyleで区別しています。
  color= colors, # 色を指定します。
  legend = True
  )

ax.set(
  xlim = (0,None), # 0から表示させます。
  ylim = (0,None), # 0から表示させます。
  title = "Scatter plot of Iris",
  xlabel = "sepal width",
  ylabel = "sepal length"
  )

ここで話が出てきそうなのが、x軸とy軸の比率です。グラフが見やすくなって、0始まりは問題ないのですが、x軸とy軸の比率が異なります。

これは第1章でも記載していますが、対応方法が2種類あります。そのひとつがax.set_aspect("equal")とするものです。その場合はこちらのようになります。

これを見たときに、なんか違うという思いが出てこなかったでしょうか?これを解決するにはx軸とy軸の両方を同じ最小値と最大値にしてしまうことです。

コードはこちらになります。

# 色をリストで指定する。
colors = []
for c in range(0,len(iris_data)):
  if iris_data.loc[c].species == "setosa":
    colors.append("#55BFD8")
  else:
    colors.append("lightgray")

fig, ax = plt.subplots(1,1,dpi = 300)
ax = sns.scatterplot(
  data = iris_data, 
  x = "sepal_width", 
  y = "sepal_length", 
  style = "species", 
  color= colors, 
  legend = True
  )

# x軸とy軸の最大値を読み込みます。
x_max = iris_data.sepal_width.max() * 1.02
y_max = iris_data.sepal_length.max() * 1.02

# x軸とy軸を比較して最も大きい値に合わせます。
if x_max > y_max:
  axis_max = x_max
else:
  axis_max = y_max

ax.set(
  xlim = (0,axis_max), 
  ylim = (0,axis_max),
  title = "Scatter plot of Iris",
  xlabel = "sepal width",
  ylabel = "sepal length",
  aspect = "equal" # 比率を等倍にします。
  )

これでうまく等倍のグラフとなりました。

ちょっとした工夫でも

見た目が大きく変わり、訴求効果も変わってきます。あなたが素晴らしいデータを持っていたとしても、それをうまく伝えられなければもったいないです。

このようにただの棒グラフかもしれませんが、僅かな努力で大きな効果が得られるのであればリターンとしては十分でしょう。ぜひいろいろチャレンジしてみてください。