俺のOneNote

俺のOneNote

データ分析が仕事な人のOneNote愛とか、分析小話とか。

XKCDスタイルによるゆるふわPython Data Visualization

matplotlib の XKCDスタイルを適用して、ゆるふわVizを作ってみようというお話です。

XKCDについては以下をご参照ください。

matplotlib.org

xkcd.com

基本的に、matplotlibオブジェクトの描写コードをwith構文内に仕込めむだけの単純作業です。

import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
import pandas as pd
sns.set()
df = sns.load_dataset("titanic")

普通の描写だと

idx = df["embark_town"].value_counts().index
val = df["embark_town"].value_counts().values
width = 0.6      
plt.figure(figsize=(8,4),facecolor="white")
plt.barh(idx, val, width)
for x, y in zip(val, idx):
    plt.text(x, y, x, ha='left')
plt.ylabel('Embark town')
plt.title('Record counts by embark town')
plt.show()

f:id:kopaprin:20200517142822p:plain

XKCDスタイルを適用してみます。

with plt.xkcd():
  width = 0.6      
  plt.figure(figsize=(8,4),facecolor="white")
  plt.barh(idx, val, width)
  for x, y in zip(val, idx):
      plt.text(x, y, x, ha='left')
  plt.ylabel('Embark town')
  plt.title('Record counts by embark town')
  plt.show()

f:id:kopaprin:20200517143011p:plain

seabornの統計グラフでもきちんと機能します。

with plt.xkcd():
  plt.figure(figsize=(8,5),facecolor="white")
  sns.distplot(df[df["survived"]==1]["age"])
  sns.distplot(df[df["survived"]==0]["age"])
  plt.legend(["survived : 1","survived : 0"])
  plt.title("Age distribution by survived")
  plt.show()

f:id:kopaprin:20200517143201p:plain

scatter plot系はそんなに変わり映えしません。

np.random.seed(19680801)
N = 100
r0 = 0.6
x = 0.9 * np.random.rand(N)
y = 0.9 * np.random.rand(N)
area = (20 * np.random.rand(N))**2 
c = np.sqrt(area)
r = np.sqrt(x ** 2 + y ** 2)
area1 = np.ma.masked_where(r < r0, area)
area2 = np.ma.masked_where(r >= r0, area)
with plt.xkcd():
  plt.figure(figsize=(6,6),facecolor="white")
  plt.scatter(x, y, s=area1, marker='^', c=c)
  plt.scatter(x, y, s=area2, marker='o', c=c)
  theta = np.arange(0, np.pi / 2, 0.01)
  plt.plot(r0 * np.cos(theta), r0 * np.sin(theta))
  plt.show()

f:id:kopaprin:20200517143353p:plain

個人的にbox plot、violin plotの描写が可愛らしくてすきです。

with plt.xkcd():
  f, ax = plt.subplots(figsize=(7, 6))
  ax.set_xscale("log")
  planets = sns.load_dataset("planets")
  sns.boxplot(x="distance", y="method", data=planets,
              whis=[0, 100], palette="vlag")
  sns.swarmplot(x="distance", y="method", data=planets,
                size=2, color=".3", linewidth=0)
  ax.xaxis.grid(True)
  ax.set(ylabel="")
  sns.despine(trim=True, left=True)

f:id:kopaprin:20200517143539p:plain

Horizontal boxplot with observations — seaborn 0.10.1 documentation

sns.set(style="whitegrid", palette="pastel", color_codes=True)
tips = sns.load_dataset("tips")

with plt.xkcd():
  plt.figure(figsize=(6,4))
  sns.violinplot(x="day", y="total_bill", hue="smoker",
                split=True, inner="quart",
                palette={"Yes": "y", "No": "b"},
                data=tips)
  sns.despine(left=True)

f:id:kopaprin:20200517143647p:plain

Grouped violinplots with split violins — seaborn 0.10.1 documentation

たまーに使ってみたくなる楽しげなstyleです。 多少のジョークがきくプレゼンや、資料に差し込んでみるのがよさそうです。