2016年12月20日火曜日

matpotlib.pyplot で縦横比を1:1に


まずは結果図




物理モデルを組み立てて計算して、その結果を表示したら物理モデルのジオメトリと全然違う!
なんてことはよくある。
それは、matplotlib.pyplot が頭がいいため。
勝手に縦横スケールを最適にしてくれるのだ。
しかしこれでは勝手が良くないので、もちろん縦横比を1:1にしてくれる方法は用意されている。

pylab_examples example code: equal_aspect_ratio.py
要は公式サイトの例に従って

plt.axes().set_aspect('equal', 'datalim')

を入れればいいだけだ。


This page shows how to set the aspect ratio to equal.
このページでは図のアスペクト比、つまり縦横比を1:1にする方法を示します。
In [1]:
%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
In [2]:
t = np.linspace(0,2*np.pi,100)
x = np.cos(t)
y = 0.1*np.sin(t) # 縦は-0.1から0.1まで
In [3]:
plt.figure(figsize=(3,3))
plt.plot(x,y)
Out[3]:
[<matplotlib.lines.Line2D at 0x1521a479a20>]
In [4]:
plt.figure(figsize=(3,3))
plt.plot(x,y)
plt.axes().set_aspect('equal', 'datalim')
plt.savefig("./aspect_ratio.png",dpi=250)

matplotlib.pyplot で複数のプロットを綺麗に重ねる


結果図はこちら



グラフを書いていると、同じグラフ内に複数のデータを表示したいときがある。
subplotで分けるのもいいが、例えば「クロックとそれに同期した伴う信号の伝搬」などは、そこまでするのは不適。
こんなときは、一つのグラフに複数を重ねてしまえばよい。

重ねるとはいっても、上下に全く重ねてしまうと何もわからなくなるので、
しっかりオフセットをつける。

加えて、グラフのデータごとに色分けをして、軸ラベルも同じ色にする。
表示すべき軸目盛りは、リストに入れておく。

あとは自動で表示してくれるとうのが、下記のプログラムのコンセプト

In [1]:
%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
In [2]:
t = np.linspace(-2*np.pi,2*np.pi,500)
y1 = np.sin(t)
y2 = np.cos(t)
y3 = np.abs(np.sin(t))
y4 = np.sin(t)**2
c1,c2,c3,c4 = "blue","green","red","black" # 各プロット、y軸目盛りの色
l1,l2,l3,l4 = "sin","cos","abs(sin)","sin**2" # 各ラベル
o1,o2,o3,o4 = 0,3,5,7 # 各オフセット
labels1 = [-1,0,1]
labels2 = [-1,0,1]
labels3 = [0,1]
labels4 = [0,1]
yticks1 = [la+o1 for la in labels1]
yticks2 = [la+o2 for la in labels2]
yticks3 = [la+o3 for la in labels3]
yticks4 = [la+o4 for la in labels4]
In [3]:
ytls = labels1+labels2+labels3+labels4
ytks = yticks1+yticks2+yticks3+yticks4
In [4]:
plt.figure(figsize=(6,5),facecolor="w")
plt.plot(t,y4+o4,color=c4,label=l4)
plt.plot(t,y3+o3,color=c3,label=l3)
plt.plot(t,y2+o2,color=c2,label=l2)
plt.plot(t,y1+o1,color=c1,label=l1)

plt.ylim(o1-2,o4+2)

plt.yticks(ytks)
plt.axes().set_yticklabels(ytls)
plt.legend(loc="upper right",fontsize=8)
plt.xlim(-2*np.pi,2*np.pi)
labs = plt.axes().get_yticklabels()
for i in range(len(labs)):
    if i < len(labels1):
        labs[i].set_color(c1)
    elif i < len(labels1+labels2):
        labs[i].set_color(c2)
    elif i < len(labels1+labels2+labels3):
        labs[i].set_color(c3)
    else:
        labs[i].set_color(c4)
plt.savefig("./align_waveforms.png",dpi=250,bbox_inches="tight",pad_inches=0.02)

2016年12月17日土曜日

甘くないコーヒー飲料

アブダビ出張に行った時、スーパーで適当に買ってきたこれ



すごく美味しかった。

コーヒーは美味しいものは美味しいけど、下手に大量に飲むとすぐ気持ち悪くなる。
・セブンイレブンのコーヒー/アイスカフェラテ
・ファミリーマートのカフェラテ
は美味しくて気持ち悪くならないということがわかってきたので、
ふとインスタントコーヒーを買ってみたのだ。

内容物は
・Cofee Creamer
・Foaming Booster
・Instant Soluble Coffee
・Sugar
・Salt
・Contains milk
の順。砂糖が入ってはいるけど、全然甘くない。
(Foaming Booster ってなんだ…)

帰国後飲んで、「カップチーノうま」って思ったから日本でも探した。
でも、日本のネスカフェでは扱ってなく、輸入品しかない(バカ高い)

スーパーで売ってるやつをいくつか試すと、すごく甘い。
日本のやつはなんで大量の砂糖が入ってるんだろう。
なにが「AGF Blendy 濃厚クリーミーカプチーノ」だ「激甘コーヒー飲料」にでも改名すればいいのに。
ギリギリ耐えられるのが「AGF Blendy 濃厚ビターカフェラテ」。
ビターってなんだという甘さ。
正直おいしくない。

もっと買ってくればよかったと後悔してもし切れない。

食器洗い乾燥機



これ、欲しい。

食器洗いはなんだかんだ時間がかかるし面倒。
入れてスイッチONで綺麗になるなら必要でしょう。

QOLに課金していきたい。

(でも乾燥機能はいるのか…?放置しておけば乾燥されないか…?)

乾燥機能のないモデル(NP-TCB1-W)は設置工事別で25,000円くらい。

2016年12月14日水曜日

matplotlib.pyplot で レジェンドを二つ

グラフのパラメータがたくさんあるとき、
「色」、「線種」
を変えると見やすく、わかりやすくなる。
そんなとき、レジェンドが二つ欲しくなる。

レジェンドを二つ作るには、次のようにすればよい。




In [1]:
%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
In [2]:
plt.figure(figsize=(4,3))

l1, = plt.plot([0,1],[1,0],label="l1")
l2, = plt.plot([0,1],[1.1,0],label="l2")
l3, = plt.plot([0,1],[1.2,0],label="l3")
h1 = [l1, l2, l3]
l4, = plt.plot([0,1],[0,1],"--",label="l4")
l5, = plt.plot([0,1],[0,1.1],"--",label="l5")
h2 = [l4, l5]

lab1 = [ h.get_label() for h in h1]
lab2 = [ h.get_label() for h in h2]

leg1 = plt.legend(h1,lab1, loc=1)
leg2 = plt.legend(h2,lab2, loc=4)

plt.gca().add_artist(leg1) # 最後の legend しか自動認識してくれない
plt.show()

matplotlib.pyplot で 縦に二つ並べたグラフに一つの縦軸ラベル

グラフは二つあるけれど、
y軸はどっちも同じ。
どっちにもy軸ラベルを書くのはアホらしい。

そんなときは、

matplotlyb.pyplot で y軸ラベルの位置を揃える

と同様に、yaxis.set_label_coords で位置を調節し、
軸ラベルを一つだけにする。
すると、立派なグラフができる。



In [1]:
%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
In [2]:
plt.figure(figsize=(3,2))
ax1 = plt.subplot(2,1,1)
ax2 = plt.subplot(2,1,2)
ax1.set_ylabel("y Axis")
plt.setp(ax1.get_xticklabels(),visible=False)
ax1.yaxis.set_label_coords(-0.16,-0.1)