keisukeのブログ

***乱雑です!自分用のメモです!*** 統計や機械学習の勉強と、読み物を書く練習と、備忘録用のブログ

matplotlibで背景の色や透明度を設定する - How to set the background color and transparency in matplotlib

参考:matplotlib公式のArtist tutorial
f:id:kaisk:20141130164243p:plain

JP

matplotlibでプロットの背景の色や透明度の設定方法:

>>> import matplotlib.pyplot as plt
>>> fig = plt.figure()  # Figure
>>> ax = fig.add_subplot(211)  # Axes
>>> fig.patch.set_facecolor('blue')  # 図全体の背景色
>>> fig.patch.set_alpha(0.5)  # 図全体の背景透明度
>>> ax.patch.set_facecolor('green')  # subplotの背景色
>>> ax.patch.set_alpha(0.3)  # subplotの背景透明度

subplotの緑色の透明度が0.3と低いので図全体の背景色の青に負けていますね

EN

How to set the plot's background color or transparency in matplotlib:

>>> import matplotlib.pyplot as plt
>>> fig = plt.figure()  # Figure
>>> ax = fig.add_subplot(211)  # Axes
>>> fig.patch.set_facecolor('blue')  # change the background color of the figure
>>> fig.patch.set_alpha(0.5)  # change the background transparency of the figure
>>> ax.patch.set_facecolor('green')  # change the background color of the subplot
>>> ax.patch.set_alpha(0.3)  # change the background transparency of the subplot

Because the transparency of subplot's background green is 0.3, it seems like blue which is the Figure's background color.

「情報系」と「電気系」は同じ学部?

歴史的な事情もあって,「情報系」と「電気系」は同じカテゴリにされることが多いけど,情報系と電気系とは本質的に関係はないと思う.

これまでの科学で計算機を構築するためには電気回路が都合が良かっただけで,もしもメカニカルな機構のほうが効率が良かったら機械系と情報系が同じカテゴリにされていただろうし,粘菌コンピュータのほうが効率がよかったら生物系と情報系が同じカテゴリにされていただろう.

情報系は電気回路を手段として使っているだけであって,本質的に学問したいのは仮想的な計算機なことが多い(チューリングマシンオートマトンコンパイラ等).
電気系と情報系を同じカテゴリにするのは,「数学はギリシア文字をたくさん使うからギリシア文学と同じカテゴリ」って言ってるのと近いものを感じる.

Python format string

Pythonのstringには.format()というフォーマット指定子のメソッドが用意されています.
C言語のsprintfをするときのように,文字列に他の文字を埋め込みたいときに使うやつです.
例えば,次のように使います:

>>> a = 'hoge'
>>> b = 123
>>> c = 3.14
>>> # format指定子
>>> print('a is {0}, b is {1}, and c is {2}.'.format(a,b,c))
>>> # %指定子
>>> print('a is %s, b is %d, and c is %f.' % (a,b,c))

個人的には%指定子のほうをよく使っていたのですが,.formatのほうが柔軟かつ推奨されているということでできるだけ.formatを使うことにしました.
.formatと%の違いで一番大きいことは,.formatでは(おそらく)オブジェクトの__str__メソッドを呼び出して文字列型に変換しているので,ユーザが型を意識せずに単に{0}などと書けば良いのに対し,%では%d,%f,%sなどのようにユーザが型を意識してフォーマットを出力する必要があることだと思います.
.formatのほうがよりダックタイピングらしさがありpythonicで良いっぽい雰囲気です.

.formatで便利そうなTipsをまとめると,

各指定子{0}の数字は省略可能.
>>> print('a is {}, b is {}, and c is {}.'.format('hoge', 123, 3.14))  # この場合,順番が考慮される
各指定子は変数名でアクセス可能(.formatは辞書形式).
>>> print('a is {a}, b is {b}, and c is {c}.'.format(c=3.14, b=123, a='hoge'))  # この場合,辞書形式なので順番は関係ない

よって,locals()をformatにそのまま投げることで今使っている変数名でそのまま文字列に埋め込み可能.

>>> a = 'hoge'
>>> b = 123
>>> c = 3.14
>>> print('a is {a}, b is {b}, and c is {c}.'.format(**locals()))

便利です*1

*1:locals()に**している理由: format()は辞書そのものを引数にはとらない(locals()は辞書を返す)ので,**で辞書を展開する必要があるため.つまり,.format({'a':'hoge', 'b':123})はダメなので,**によって.format(a:'hoge', b:123)へと展開している

【Google Calendar】Googleカレンダーの背景;日曜日を赤,土曜日を青にする

Googleカレンダーの日曜日の行を赤,土曜日の行を青で表示したいときは,
Stylishで次を追加すれば良い:
(If you want to color background of Sundays for red, Saturdays for blue in Google Calendar,
you can add the following code in Stylish:)

@namespace url(http://www.w3.org/1999/xhtml);
@-moz-document url-prefix("http://www.google.com/calendar/"), url-prefix("https://www.google.com/calendar/"){
 
/* background color for day cells; Sundays. */
  div.month-row:nth-child(1) > table:nth-child(1) > tbody:nth-child(1) > tr:nth-child(1) > td:nth-child(1) {
    background: #ffe5e5;
  }
  div.month-row:nth-child(2) > table:nth-child(1) > tbody:nth-child(1) > tr:nth-child(1) > td:nth-child(1) {
    background: #ffe5e5;
  }
  div.month-row:nth-child(3) > table:nth-child(1) > tbody:nth-child(1) > tr:nth-child(1) > td:nth-child(1) {
    background: #ffe5e5;
  }
  div.month-row:nth-child(4) > table:nth-child(1) > tbody:nth-child(1) > tr:nth-child(1) > td:nth-child(1) {
    background: #ffe5e5;
  }
  div.month-row:nth-child(5) > table:nth-child(1) > tbody:nth-child(1) > tr:nth-child(1) > td:nth-child(1) {
    background: #ffe5e5;
  }
  div.month-row:nth-child(6) > table:nth-child(1) > tbody:nth-child(1) > tr:nth-child(1) > td:nth-child(1) {
    background: #ffe5e5;
  }
  
/* background color for day numbers; Sundays.   */
  div.month-row:nth-child(1) > table:nth-child(2) > tbody:nth-child(1) > tr:nth-child(1) > td:nth-child(1){
    background: #ffe5e5;
  }
  div.month-row:nth-child(2) > table:nth-child(2) > tbody:nth-child(1) > tr:nth-child(1) > td:nth-child(1){
    background: #ffe5e5;
  }
  div.month-row:nth-child(3) > table:nth-child(2) > tbody:nth-child(1) > tr:nth-child(1) > td:nth-child(1){
    background: #ffe5e5;
  }
  div.month-row:nth-child(4) > table:nth-child(2) > tbody:nth-child(1) > tr:nth-child(1) > td:nth-child(1){
    background: #ffe5e5;
  }
  div.month-row:nth-child(5) > table:nth-child(2) > tbody:nth-child(1) > tr:nth-child(1) > td:nth-child(1){
    background: #ffe5e5;
  }
  div.month-row:nth-child(6) > table:nth-child(2) > tbody:nth-child(1) > tr:nth-child(1) > td:nth-child(1){
    background: #ffe5e5;
  }
  
/* background color for day cells; Saturdays.  */
  div.month-row:nth-child(1) > table:nth-child(1) > tbody:nth-child(1) > tr:nth-child(1) > td:nth-child(7){
    background: #e5e5ff;
  }
  div.month-row:nth-child(2) > table:nth-child(1) > tbody:nth-child(1) > tr:nth-child(1) > td:nth-child(7){
    background: #e5e5ff;
  }
  div.month-row:nth-child(3) > table:nth-child(1) > tbody:nth-child(1) > tr:nth-child(1) > td:nth-child(7){
    background: #e5e5ff;
  }
  div.month-row:nth-child(4) > table:nth-child(1) > tbody:nth-child(1) > tr:nth-child(1) > td:nth-child(7){
    background: #e5e5ff;
  }
  div.month-row:nth-child(5) > table:nth-child(1) > tbody:nth-child(1) > tr:nth-child(1) > td:nth-child(7){
    background: #e5e5ff;
  }
  div.month-row:nth-child(6) > table:nth-child(1) > tbody:nth-child(1) > tr:nth-child(1) > td:nth-child(7){
    background: #e5e5ff;
  }
  
/* background color for day numbers; Saturdays.  */
  div.month-row:nth-child(1) > table:nth-child(2) > tbody:nth-child(1) > tr:nth-child(1) > td:nth-child(7){
    background: #e5e5ff;
  }
  div.month-row:nth-child(2) > table:nth-child(2) > tbody:nth-child(1) > tr:nth-child(1) > td:nth-child(7){
    background: #e5e5ff;
  }
  div.month-row:nth-child(3) > table:nth-child(2) > tbody:nth-child(1) > tr:nth-child(1) > td:nth-child(7){
    background: #e5e5ff;
  }
  div.month-row:nth-child(4) > table:nth-child(2) > tbody:nth-child(1) > tr:nth-child(1) > td:nth-child(7){
    background: #e5e5ff;
  }
  div.month-row:nth-child(5) > table:nth-child(2) > tbody:nth-child(1) > tr:nth-child(1) > td:nth-child(7){
    background: #e5e5ff;
  }
  div.month-row:nth-child(6) > table:nth-child(2) > tbody:nth-child(1) > tr:nth-child(1) > td:nth-child(7){
    background: #e5e5ff;
  }
}

ちなみに,これは月ビューの一番左の行を赤,右の行を青にしているだけなので,「日曜始まり」かつ「月ごと」の表示にしていないと意味なし.
(Note: because this code simply color the most left to red and most right to blue in monthly-view, please use "monthly-view" and "Sundays most left view".)

【Python】ふたつの配列からすべての組み合わせを評価

引数をふたつとる関数f([x,y])が存在するとします(この場合は引数2つではなく、要素数2の配列をひとつ引数にとるのほうが正しいですが・・・)。
たとえば、f([x,y]) = x+y などです。
このfはうまく実装されているので、f([[1,3], [2,4]])とすると(つまり[1+3, 2+4])、
[f([1,3]), f([2,4])]としたのと同じ効果(つまり[1+3, 2+4])を持ちます(これはnumpyやmatlabならお馴染みの設計だと思います)。

では、この関数fの引数x,yについて、候補が複数あったらどうなるでしょう?
そしてその候補を重複なく選んですべて評価したいときはどうすればよいでしょう?
つまり、x=[1,2,3]、y=[4,5]について、f([1,4]), f([1,5]), f([2,4]), f([2,5]), f([3,4]), f([3,5]) のように評価したいわけです。

ナイーブに考えると、こうなります:

>>> import numpy as np
>>> x = np.array([1,2,3])
>>> y = np.array([4,5])
>>> ret = [f([xi,yi]) for xi in x for yi in y]

しかしこれではせっかくfが引数を行列として処理できるように実装されているのに、それを活かせません。処理速度も遅くなる場合が大半だと思います。
このような場合、numpyのmeshgridが使えます:

>>> xx, yy = np.meshgrid(x, y)
>>> ret = f(np.c_[xx.ravel(), yy.ravel()])

パッと見だと何やってるかよくわかりづらいと思うので解説します。

まず、xx, yy = np.meshgrid(x,y)は、xx = np.tile(x, (len(y),1); yy = np.tile(y, (len(x),1).T; と同じです。サイズがlen(y) X len(x)の行列をふたつ作ります。
先ほどの例で言うと、xx=[[1,2,3],[1,2,3]], yy=[[4,4,4],[5,5,5]]となります。
この時点で、ふたつの行列xx,yyのインデックスi,jを順番に見ていくと、(i,j)=(0,0)のとき[1,4]、(i,j)=(0,1)のとき[2,4]、などとなり、すべての組み合わせを重複なく選べそうになっています。
続いてのxx.ravel(), yy.ravel()ですが、これは単純にxxとyyをバラバラにするだけです。xx.ravelをすると、[1,2,3, 1,2,3], yy.ravel()をすると[4,4,4, 5,5,5]となります。
次にnp.c_[]ですが、これは与えられたオブジェクトの第二軸(second axis)をもとに合体させます。この場合、np.c_[ [1,2,3, 1,2,3], [4,4,4, 5,5,5] ] は、[[1,4],[2,4],[3,4], [1,5],[2,5],[3,5]]となります。
これをfに与えれば、やりたかった重複なくすべての組み合わせの評価ができます。

実際こんなの何に使うのかというと、格子点すべてで関数を評価するときに便利です。
\begin{align*}y>-x^2\end{align*}を視覚化したいとしましょう。これは\begin{align*}y+x^2>0\end{align*}ですから、視覚化するときは、あらゆる(x,y)の組に対して\begin{align*}y+x^2>0\end{align*}が成立すれば黄、しなければ青でグラフを塗りつぶせば良いです。このあらゆる(x,y)の組というのが、np.meshgrid()で作れます。

>>> import numpy as np
>>> import matplotlib.pyplot as plt
>>> x = np.arange(-2,2, 0.01)
>>> x2 = x**2
>>> y = np.arange(-5,0, 0.01)
>>> xx, yy = np.meshgrid(x2,y)
>>> arg = np.c_[xx.ravel(), yy.ravel()]
>>> ret = np.sum(arg, axis=1)  # calc x^2+y
>>> plt.contourf(x, y, ret.reshape(xx.shape)>0, cmap=plt.cm.Paired, alpha=0.8)
>>> plt.show()

f:id:kaisk:20141105040848p:plain

【Python】max/minのindex

Pythonでmax/minのではなく、そのindexを取るためには、

>>> x = [2, 3, 0, 1]
>>> max_idx = x.index(max(x))
>>> min_idx = x.index(min(x))

みたいな微妙に歯がゆい書き方をしないといけない(しかも、index()とmax()/min()で二回探索しててアホっぽい)のが気になる。
もちろんnumpyにはargmax/argminがあるけど、標準ライブラリレベルで実装してほしい。
matlabみたいに、max()/min()の返り値を最大値/最小値だけじゃなくてそのインデックスとのタプルとかにしちゃえばいいのに・・・(後方互換が完全に消えるからPython3のドサクサにまぎれてやっとけばよかったのに!)

numpyのshuffleとpermutationの違い

python - shuffle vs permute numpy - Stack Overflow

numpyにはshuffle(x)とpermutation(x)というほぼ同じ機能の関数があります.
どちらも,配列をランダムに並び替えますが,違いが2つあります.

ひとつは,shuffle(x)は配列をin-placeで並び替えるが,permutation(x)は並び替えた配列のコピーを生成するという点です.つまり:

>>> import numpy as np
>>> x = np.array([1,2,3,4,5])
>>> y = np.random.permutation(x)
>>> # y : [3,1,4,2,5]
>>> # x : [1,2,3,4,5]
>>>
>>> x = np.array([1,2,3,4,5])
>>> y = np.random.shuffle(x)
>>> # y : None
>>> # x : [5,2,3,4,1]

もうひとつの違いは,permutation(x)には配列だけでなくint型整数も渡せるという点です.
permutation(5)は,permutation(list(range(5)))と同じ働きをします.(permutation(arange(5))でも同じです.)