プロクラシスト

今日の寄り道 明日の近道

【技術メモ】python matplotlibで見栄えの良い色, グラフを作るTips


スポンサーリンク

matplotlibでも割と綺麗な図を作ることができる。 図示の時に色々と使うテクニックを列挙。

どうぞ皆さんもお使いください

基本の体裁

まずこのグラフ

import numpy as np
import matplotlib.pyplot.plt
x = np.arange(-np.pi,np.pi,np.pi/50)
plt.axvspan(-0.5*np.pi,0.5*np.pi,color="red")
plt.plot(x,np.sin(x))
plt.show()

f:id:imslotter:20170423210018p:plain

どぎついし、端が切れているし、イマイチ。この辺の体裁を整えていく

関数で調整

変えたい 関数 選択肢
x,yの範囲 plt.xlim(a,b)
plt.ylim(a,b)
範囲を実数値で
タイトル plt.title("hoge") タイトルをstr型で

plt.legend(loc=2)

などとするとタイトルやラベルが表示される。locオプションはラベルの場所を決める。グラフの第一から第四象限と場所が対応。loc="lower right"などという書き方も可能

plt()内の基本オプションで調整

変えたい オプション 選択肢
色(デフォルト) color="red"など red, green, blue, cyan, magenta, yellow, black
色(自分で) color="#010101"など Materialui : 最近はやりのマテリアルデザイン
などのカラーコード載っている。
クリックしてctrl+Cでコピーする。
色選びの参考に。
太さ lw 整数値(大きいほど太い)
マーカー marker “o"や"x"などだけではなく、
様々なマーカーが用意されている。
このサイトが詳しい
マーカーサイズ markersize 整数値(大きいほど大きい)
ラベル label グラフを表すラベル。$$で囲むと数式もOK
透過度 alpha 0≦alpha≦1, 大きいほど透明度が高い
x = np.arange(-np.pi,np.pi,np.pi/50)
plt.axvspan(-0.5*np.pi,0.5*np.pi,alpha=1.0,color="#ffcdd2",label="$(-\pi/2, \pi/2)$")
plt.plot(x,np.sin(x),lw=3,color="#03A9F4", label="$y = \sin{x}$")
plt.xlim(-np.pi,np.pi)
plt.ylim(-1,1)
plt.title("modification")
plt.legend(loc="lower right")
plt.savefig("graph_modifcation.png")

こんな感じになる

f:id:imslotter:20170423210039p:plain

透過度をあげる

線が重なったり、点が密集した時は、先述のalphaオプションを使って透明度をあげてやると分布もわかりやすく見やすい図になる。 例えば、x,yに正規分布で乱数を発生させたものを散布図でプロットする

x = np.random.normal(0,1,1000)
y = np.random.normal(0,1,1000)
plt.figure(figsize=(10,5))
plt.subplot(121)
plt.scatter(x, y,marker="o")
plt.subplot(122)
plt.scatter(x, y, marker="o",alpha=0.2)
plt.show()

f:id:imslotter:20170423213934p:plain

左のほうが綺麗で見やすい(はず)

漫画風にする

import matplotlib.pyplot as plt
plt.xkcd()

とすればOK 詳しくはこちら

棒グラフに柄を載せる

これもちょっとしたテクニック。 棒グラフを書くplt.bar()のオプションhatchを使う

t = range(10)
y1 = [x for x in  range(len(t))]
y2 = [1.0*x**2/9 for x in  range(len(t))]
w = 0.4 # 棒の幅
tick_interval = 2 #目盛りの間隔
left1 = [x-w/2 for x in range(len(t))]
left2 = [x+w/2 for x in range(len(t))] # 棒の幅分ずらす
labels = [year for i,year in enumerate(t) if i%tick_interval == 0] #目盛りの設定

plt.figure(figsize=(16,8))
plt.subplot(121)
plt.bar(left1, y1 , align='center',width=w)
plt.bar(left2, y2, align='center',width=w)
plt.xticks(range(0,len(t),tick_interval),labels)
plt.legend(loc=2)
plt.subplot(221)
plt.bar(left1, y1 , align='center',width=w)
plt.bar(left2, y2, align='center',width=w)
plt.subplot(222)
plt.bar(left1, y1 , align='center',width=w,color="#404040")
plt.bar(left2, y2, align='center',width=w,color="#808080",hatch="/")
plt.subplot(223)
# 数を増やすと密になる
# "//"以外にも色々な模様が用意されている
plt.bar(left1, y1 , align='center',width=w,color="#808080",hatch="////")
plt.bar(left2, y2, align='center',width=w,color="#909090",hatch="xx")
plt.subplot(224)
plt.bar(left1, y1 , align='center',width=w,color="#808080",hatch = "--")
plt.bar(left2, y2, align='center',width=w,color="#909090",hatch="oo")
plt.xticks(range(0,len(t),tick_interval),labels)
plt.legend(loc=2)

f:id:imslotter:20170423213847p:plain

グラデーション用の色を作る

グラデーションの作り方

  • いちいち変えるの面倒だけどパラメータが多い
  • グラデーション的に変えたい

そういう時はimport matplotlib.cm as cmを使う

import matplotlib.pyplot as plt
import matplotlib.cm as cm
import numpy as np
x =np.linspace(0,2*np.pi,100)
for i in range(30):   
    plt.plot(x,i*np.sin(x),color=cm.hsv(i/30.0))
plt.xlim(0,2*np.pi)
plt.show()

色の参考にcmリスト

  • さっきのcm.hogeの所を色々変えてみたものを図示
  • [0,1]のグラデーションになっていて,一番平らなのが0,盛り上がっているのが1

可視化の参考にどうぞ

王道カラフル系

  • hsv
  • jet
  • spectral f:id:imslotter:20170423213408p:plain

単色濃淡(っぽい)

  • bone
  • gray
  • pink
  • copper

f:id:imslotter:20170423213526p:plain

温度系

  • cool
  • hot

f:id:imslotter:20170423213543p:plain

季節の色たち

  • spring
  • summer
  • autumn
  • winter

f:id:imslotter:20170423213600p:plain

グラデーションにならない系

  • flag
  • prism

f:id:imslotter:20170423213616p:plain

その他

公式HP

PROCRASIST