2015年5月30日土曜日

Zenfone2を手に入れた

IDEOSでは、OCN mobileのデータSIMを利用していたのですが、 3Gでしか利用していなかったので、ちょっともったいない気がしていました。 画面が小さいため、ほぼモバイルルーターとしてしか使用しないという状況。 Zenfone2が発売されたので、乗り換えました。 メモリ2GB、ストレージ32GBのモデルです。 IDEOSでもmicro SIMを使っていたので、SIMを入れ替えるだけですぐに使えました。 データSIMだけど、セルスタンバイ1%だって。問題がない様子。 画面をダブルタップで、スリープのON/OFFができるのはとても便利ですね。

QPythonを入れてみたところ、便利な計算機として、使えそうではあります。 さらにkivyを用いて、PC上でimageViewerを書き、Zenfone2へインストールしてみました。 しかしながら、QPythonではいるkivyのバージョンは1.8で、バージョン1.9からの in-memory loadingを利用したため、QPythonからは実行できませんでした。

Kivyのページを見たところ、AndroidにはKivy Launcherというものがあるらしいので、 そちらで試すことに。 Kivy Launcherは、kivyのバージョンが1.9で、無事に動作しました。 これで、PC上で作成したGUIつきのpythonスクリプトを、Zenfone2でもそのまま動かせそうです。

2015年5月23日土曜日

matplotlibのMultiCursor AutoScale時の挙動修正

matplotlibのMultiCursor()の使い方は、公式のページにありますが、matplotlib 1.3.0あたりからクロスラインカーソルも利用できます。

multi = MultiCursor(fig.canvas, (ax1, ax2), color='r', lw=1, horizOn=True)
のように、horizOnキーワード引数にTrueを渡すと水平線を描画します。

ここで、クロスラインカーソルを表示したいaxes、(ax1, ax2)を渡しているのですが、
最後のax2でないaxes、ここではax1の軸がオートスケールになっていると、あれっ?
と思う挙動をします。

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import MultiCursor

t = np.arange(0.0, 2.0, 0.01)
s1 = np.sin(2*np.pi*t)+400
s2 = np.sin(4*np.pi*t)
fig = plt.figure()
ax1 = fig.add_subplot(211)
ax1.plot(t, s1)

ax2 = fig.add_subplot(212, sharex=ax1)
ax2.plot(t, s2)

multi = MultiCursor(fig.canvas, (ax1, ax2), color='r', lw=1, horizOn=True)
plt.show()
ax1に描画する波形を400だけオフセットしただけですが、実行すると、以下のようになります。
y軸のレンジが0からになってしまいます。 オートスケールで期待する結果とは異なります。 matplotlibパッケージのwidgets.pyにある、MultiCursorのクラスを見てみると、 どうやら、カーソル線の初期位置の計算に、渡したaxesの最後のものだけを使っているために 生じるようです。

これをwidgets.pyをいじらずに回避するには、MultiCursorの__init__()で行なわれる カーソル線の生成を、別に行えばよさそうです。 そこで、MultiCursorの__init__()には、vertOn、 horizOnともにFalseを渡します。
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import MultiCursor

class MyMultiCursor(MultiCursor):
    def __init__(self, canvas, axes, 
            useblit=True, horizOn=True, vertOn=True, **lineprops): 
        MultiCursor.__init__(self, canvas, axes, 
                useblit=useblit, horizOn=False, vertOn=False, **lineprops)

        xmids = [0.5 * (xmin + xmax) for xmin, xmax in [ax.get_xlim() for ax in axes]] 
        ymids = [0.5 * (ymin + ymax) for ymin, ymax in [ax.get_ylim() for ax in axes]] 

        if self.useblit:
            lineprops['animated'] = True
        if vertOn:
            self.vlines = [ax.axvline(xmids[i], visible=False, **lineprops)
                           for i, ax in enumerate(axes)]
        else:
            self.vlines = []

        if horizOn:
            self.hlines = [ax.axhline(ymids[i], visible=False, **lineprops)
                           for i, ax in enumerate(axes)]
        else:
            self.hlines = []

        self.vertOn, self.horizOn = vertOn, horizOn


t = np.arange(0.0, 2.0, 0.01)
s1 = np.sin(2*np.pi*t)+400
s2 = np.sin(4*np.pi*t)
fig = plt.figure()
ax1 = fig.add_subplot(211)
ax1.plot(t, s1)

ax2 = fig.add_subplot(212, sharex=ax1)
ax2.plot(t, s2)

multi = MyMultiCursor(fig.canvas, (ax1, ax2), color='r', lw=1, horizOn=True)
plt.show()

MultiCursorを継承したMyMultiCursorを利用します。 実行すると、以下のように期待されたグラフが得られました。