水曜日, 10月 27, 2010

業務用通販サイト

一息つく間もなく次の仕事の準備でお買い物作業。先輩からこのサイトを教わった。なかなか良い品揃え。個人的にも買い物したいなと思ったけど、個人相手はしていない。残念。

KAISER+KRAFT

火曜日, 10月 26, 2010

お仕事

依頼されていた作業が終わった。というか締め切りがギリギリに迫ったので、現時点での提出可能なクオリティの資料を納めた。自分の納得できるクオリティでないのが辛いけど、スケジュールを考えると仕方がないと思う。事前検討が十分だったら違っていたかもしれないけど、今回の過程で勉強が進んだ結果ここまでこなせた事を考えると、現状は必然のように思う。今後のために、やっつけで書いた処理プログラムの整備をしておくことにする。

火曜日, 10月 19, 2010

zshで算術演算を含む処理を行う

これはいかん。実にけしからん。これを覚えてしまったらzsh以外のシェルを使う気にはまったくならなくなりそうだ。というか、これを見てしまった今、心の中でそう決心しつつある。

numpyのndarrayから条件に合う値のindexを拾い出す

いまいち良い考えが思いつかないけど、取りあえずこれでどうにかしている。
a = numpy.random.randint(0,10,50)
numpy.arange(len(a))[a==5]

matplotlibで背景色を透明にする

グラフの画像出力をsavefig()で行うなら話は簡単。
savefig(filename, transparent=True)
では、それ以外(print_figure()を使うとか)では? こちらにFigureオブジェクトの属性を操作する方法が紹介されています。これを参考に以下のようにして対処することにしました。
fig = matplotlib.figure.Figure(figsize=(8,6), dpi=100)
fig.patch.set_alpha(0.0)
fig.clf()
ax = fig.add_subplot(1,1,1,position=[0.15,0.15,0.8,0.8])
ax.plot(…)
canvas = matplotlib.backends.backend_agg.FigureCanvasAgg(fig)
canvas.print_figure(filename, dpi=300)

Google ChromeにScrollbar Anywhereを使ってみた

個人的にFirefoxから離れられない最大の要因であるScrollbar AnywhereのGoogle Chrome用相当品っぽい拡張機能を偶然見つけた。名前も同じ。使ってみた感じ、chromeTouchよりも、慣れた感触に近くていい感じ。chromeTouchの作者さまには申し訳ないけど、こちらに移行します。

Chrome定住化計画がこれでまた一歩前進するかな…あとtiddly snipがあればなぁ。

月曜日, 10月 18, 2010

Macでmatplotlibを埋め込んだPyQt4のコードが上手く動かなかった件について

やっぱり先のエントリこのコードを動かすとmatplotlibのウィンドウが余計に出てしまうのは未解決と書きました。

そもそも、これは解決容易な問題かどうかです。これまで出回っているサンプルコードが自分のMac環境で正常に動作するか確認してみました。コードはこちらこちらから使用しました。結論だけいうと、何の問題はありません。極めて正常に動作しています。つまりは、自分のコードが悪いという事です。

実は気になる心当たりがありました。

    fig = matplotlib.pyplot.figure()
実はこれはここのオリジナルのコードと意図的に変えています。
    fig = matplotlib.figure.Figure()
これを変えた理由は、作成したグラフをPyQtに埋め込んで表示すると同時に、グラフの画像ファイルを生成して保存する機能を盛り込みたかったからです。自分が修正したコードでは、figから画像ファイルを生成することができます。
fig.savefig(filename)
ところが、ここをオリジナルのコードに戻しますと、matplotlibのウィンドウ複数表示がなくなり、目下の問題は解決します。要するに原因はココだったわけです。しかし、オリジナルに戻しますとfig.savefig()が使えなくなります。これでは元の木阿弥です。

解決する方法はありました。画像を生成する方法を変えればいいのです。以前から目にはなんとなく入っていたprint_figure()というものを使ってみます。こちらを参考にして修正してみます。グラフの画像ファイルを生成する部分はPyQtで表示するのとは別のバックエンド用canvasオブジェクトを生成するようにすればいいようです。

canvas = matplotlib.backends.backend_agg.FigureCanvasAgg(fig)
canvas.print_figure(filename)
以前のサンプルコードを修正したフルコードは以下のようになります。
#!/usr/bin/env python
# -*- coding: utf-8 -*-

# for command-line arguments
import sys

# Numpy functions for image creation
import numpy

# Matplotlib Figure object
import matplotlib
import matplotlib.pyplot

# Python Qt4 bindings for GUI objects
import PyQt4.QtGui

# import the Qt4Agg FigureCanvas object, that binds Figure to
# Qt4Agg backend. It also inherits from QWidget
#from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
import matplotlib.backends.backend_qt4agg
import matplotlib.backends.backend_agg

# import the NavigationToolbar Qt4Agg widget
#from matplotlib.backends.backend_qt4agg import NavigationToolbar2QTAgg as NavigationToolbar

class ApplicationWindow(PyQt4.QtGui.QMainWindow):
    """Example main window"""
    def __init__(self,figs):
        # initialization of Qt MainWindow widget
        PyQt4.QtGui.QMainWindow.__init__(self)
        # set window title
        self.setWindowTitle("Matplotlib Figure in a Qt4 Window With NavigationToolbar")
        # create a tab widget
        self.tab_widget = PyQt4.QtGui.QTabWidget(self)

        for fig, label in figs:
            # instantiate a widget, it will be the main one
            self.main_widget = PyQt4.QtGui.QWidget(self)
            self.tab_widget.addTab(self.main_widget, label)
            # create a vertical box layout widget
            vbl = PyQt4.QtGui.QVBoxLayout(self.main_widget)
            # instantiate our Matplotlib canvas widget
            qmc = matplotlib.backends.backend_qt4agg.FigureCanvasQTAgg(fig)
            # instantiate the navigation toolbar
            ntb = matplotlib.backends.backend_qt4agg.NavigationToolbar2QTAgg(
                qmc, self.main_widget)
            # pack these widget into the vertical box
            vbl.addWidget(qmc)
            vbl.addWidget(ntb)
            # # set the focus on the main widget
            # self.tab_widget.setFocus()
            # set the central widget of MainWindow to main_widget
            self.setCentralWidget(self.tab_widget)

def draw():
    figs = []

    # Standard Matplotlib code to generate the plot
    # fig = matplotlib.pyplot.figure()
    fig = matplotlib.figure.Figure()
    axes = fig.add_subplot(111)
    x = numpy.arange(0.0, 3.0, 0.01)
    y = numpy.cos(1*numpy.pi*x)
    axes.plot(x, y)
    figs.append((fig,"tab 1"))

    # fig = matplotlib.pyplot.figure()
    fig = matplotlib.figure.Figure()
    axes = fig.add_subplot(111)
    x = numpy.arange(0.0, 3.0, 0.01)
    y = numpy.cos(2*numpy.pi*x)
    axes.plot(x, y)
    figs.append((fig,"tab 2"))

    # fig = matplotlib.pyplot.figure()
    fig = matplotlib.figure.Figure()
    axes = fig.add_subplot(111)
    x = numpy.arange(0.0, 3.0, 0.01)
    y = numpy.cos(3*numpy.pi*x)
    axes.plot(x, y)
    figs.append((fig,"tab 3"))

    return figs

# Create the GUI application
qApp = PyQt4.QtGui.QApplication(sys.argv)

figs = draw()

# save image file of matplotlib graph
canvas = matplotlib.backends.backend_agg.FigureCanvasAgg(figs[0][0])
canvas.print_figure("qt4mpl.png")

# Create the Matplotlib widget
mpl = ApplicationWindow(figs)
# show the widget
mpl.show()

# start the Qt main loop execution, exiting from this script
# with the same return code of Qt application
sys.exit(qApp.exec_())
多分これで良さそうです。

日曜日, 10月 17, 2010

Python(に限らず、身の回りの各システム)の整数型の精度について

先のエントリにおいて、Pythonでの整数型の精度でハマったことについて触れました。それは確かに間違いないと思いますが、何がどう問題なのかについては放置したままです。気になりましたので、別エントリにして自分のために明記します。

こちらを見れば明らかなように、Pythonでの整数型の精度はCでのlongとして実装されているようです。これまで仕事で使用していた環境はUbuntu 10.04 32bit環境です。この場合、intもlongも32bitです。Windows XP 32bitでも動作させていましたが、この場合もint, longともに32bitです。X64ではというと、やはりintもlongも32bitですので、恐らくは問題ありません(環境は用意がありますが、まだ動作させていません)。64bit Linuxは複数のデータモデルがありますが、Ubuntu 10.04 amd64版ではintは32bitでlongは64bitでした。Snow Leopardではというと、intは32bitでlongが64bitです。

Pythonに限りませんが、バイナリファイルを扱う際には特にこれらデータモデルに気を付けてコーディングしなければなりませんね。

金曜日, 10月 15, 2010

帰宅

今週は4日しか働いていないはずなのに激しく疲労した。うち2日が肉体労働だったのが効いている。月1日だけ来られる方に飲みに誘われたけどそのまま帰ってきてしまった。

木曜日, 10月 14, 2010

仕事で書いたPythonコードがMacPortsでインストールしたバイナリで動くようにしてみた

仕事で書いたPythonコードをMacで動かす事を考えた理由は2つ。一つはコードのポータビリティを確保したい事。もう一つは、仕事のコード書きに使っているUbuntuをインストールした私物のノートPCを持ち歩かずに自宅でコード書きを続けたい、という欲求を満たすためです。

とりあえずそのまま起動してみましたが、残念ながら動きません。このコードはとあるフォーマットで作成されたバイナリファイルを読み込み、解析して表示するプログラムです。そのデータを読み込むのに一部scipy.io.numpyio.fread()を使用している(こちらを参考に)のですが、何故かMacPortsでインストールしたSciPyにはnumpyioがありません。インストールに失敗しているのかインストーラにバグがあるのか、暫く悩んでいたのですが、そもそもないように思われます。一瞬「これは困った」と考えましたが、考えてみますとscipy.io.numpyio.fread()はscipy.io.fromfile()で完全に代替可能です。何の問題もありません。

さらにプログラムが動かない理由を突き止めるべく、読み込んだデータの一部をそのまま覗いてみると、期待通りの数値になっていません。データを読み込む際にscipy.io.fromfile()のdtypeを指定する事で型指定しますが、符号付き整数を読み込む際に'l'を指定しておりました。よく考えますと、この整数型の精度はシステム依存です。32bit Linuxで正常に動いていても64bit Snow Leopardで正常に動く訳がありません。ここの整数型指定はnumpy.int32とすべきです。あと念のために'H'をnumpy.ushortに変更しておきます。これでデータを正常に読み込む事ができ、一つの問題を残して使用に問題ない形で正常な動作を得る事ができました。

一つの問題とは何かですが、先のエントリで示しましたPyQt4にmatplotlibのグラフを埋め込んで表示するコードをMacPortsバイナリで実行してみますと、確かにmatplotlibのグラフがPyQt4のウィンドウに埋め込まれた形で表示されますが、それと同時に全く同じグラフが独立したウィンドウで表示されてしまいます。Ubuntuで動かした場合は期待通りに動作し、複数のウィンドウが開かれる事はありません。恐らくは、mpl.show()がPyQt4バックエンドとしてのmatplotlib.pyplot.showIOと同義な動作をしているのではないかと推察します。残念ながらこの問題の解決方法は判りません。

金曜日, 10月 08, 2010

PyQtでショートカットを使う

PyQtの話というよりQtの話ですよね。Ctrl-QとかCtrl-Wとかでお手軽にGUIプログラムを終了できるようにしたい、という極めて安易なこと考えてみましたが、結構手間がかかりました。

調べるとsetShortcut()という関数があるので、これを使うのが早いと考え、試してみます。

        fileMenu = PyQt4.QtGui.QMenu("&File", self)
        self.action_close = fileMenu.addAction("&Close")
        self.action_close.setShortcut("Ctrl+W")
        self.menuBar().addMenu(fileMenu)
        self.connect(self.action_close, PyQt4.QtCore.SIGNAL("triggered()"), self.quit)

    def quit(self):
        sys.stdout.write("close.\n")
        qApp.quit()
一応できたにはできました。ここで、一見メニュへの登録は不要な様に見えるので取り除いてみますが、残念ながら動きません。
        self.action_close = PyQt4.QtGui.QAction("&Close", self)
        self.action_close.setShortcut("Ctrl+W")
        self.connect(self.action_close, PyQt4.QtCore.SIGNAL("triggered()"), self.quit)
できればメニュなしでもショートカットが使えるようにしたいと思います。悩んだ結果、キーボードイベントを捕まえることで解決を図りました。
#!/usr/bin/env python
# -*- coding: utf-8 -*-

# for command-line arguments
import sys

# Python Qt4 bindings for GUI objects
import PyQt4.QtGui

class ApplicationWindow(PyQt4.QtGui.QMainWindow):
    def __init__(self):
        PyQt4.QtGui.QMainWindow.__init__(self)
        self.setWindowTitle("test")

        fileMenu = PyQt4.QtGui.QMenu("&File", self)
        self.action_close = fileMenu.addAction("&Close")
        self.action_close.setShortcut("Ctrl+W")
        self.menuBar().addMenu(fileMenu)
        self.connect(self.action_close, PyQt4.QtCore.SIGNAL("triggered()"), self.quit)

    def quit(self):
        sys.stdout.write("close.\n")
        qApp.quit()

    def keyPressEvent(self, ev):
        if ev.key()==PyQt4.QtCore.Qt.Key_Q:
            if (ev.modifiers() and PyQt4.QtCore.Qt.ControlModifier):
                sys.stdout.write("quit.\n")
                qApp.quit()

# Create the GUI application
qApp = PyQt4.QtGui.QApplication(sys.argv)

# Create the Matplotlib widget
mpl = ApplicationWindow()
# show the widget
mpl.show()

# start the Qt main loop execution, exiting from this script
# with the same return code of Qt application
sys.exit(qApp.exec_())

意外にもキーボートイベントからのCtrl-Q押下の捕捉によってメニュへのショートカット(Ctrl-W)が潰される事はなく、共存して動作します。QMainWindow自体に独自のキーボードイベントはないと思いますし(あくまでも推測)、子ウィジェットからキーボードイベントが伝搬されていることが期待できるならば、この対応で問題はないかなと思うのですけど、どうなんでしょう?

PyQt使うの初めてなのにmatplotlibを埋め込んでみた

我ながら無謀と思いつつやってみた。これに書いてあったコードを殆どそのまま参考にする。

すでに書いているmatplotlibを使ったコードの転用が容易になるように、matplotlibのコードとPyQtのコードをできるだけ分離を試みてみた。(追記:以下のコード抹消、こちらに修正コード)

#!/usr/bin/env python
# -*- coding: utf-8 -*-

# for command-line arguments
import sys

# Numpy functions for image creation
import numpy

# Matplotlib Figure object
import matplotlib
import matplotlib.pyplot

# Python Qt4 bindings for GUI objects
import PyQt4.QtGui

# import the Qt4Agg FigureCanvas object, that binds Figure to
# Qt4Agg backend. It also inherits from QWidget
#from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
import matplotlib.backends.backend_qt4agg

# import the NavigationToolbar Qt4Agg widget
#from matplotlib.backends.backend_qt4agg import NavigationToolbar2QTAgg as NavigationToolbar

class ApplicationWindow(PyQt4.QtGui.QMainWindow):
    """Example main window"""
    def __init__(self,figs):
        # initialization of Qt MainWindow widget
        PyQt4.QtGui.QMainWindow.__init__(self)
        # set window title
        self.setWindowTitle("Matplotlib Figure in a Qt4 Window With NavigationToolbar")
        # create a tab widget
        self.tab_widget = PyQt4.QtGui.QTabWidget(self)

        for fig, label in figs:
            # instantiate a widget, it will be the main one
            self.main_widget = PyQt4.QtGui.QWidget(self)
            self.tab_widget.addTab(self.main_widget, label)
            # create a vertical box layout widget
            vbl = PyQt4.QtGui.QVBoxLayout(self.main_widget)
            # instantiate our Matplotlib canvas widget
            qmc = matplotlib.backends.backend_qt4agg.FigureCanvasQTAgg(fig)
            # instantiate the navigation toolbar
            ntb = matplotlib.backends.backend_qt4agg.NavigationToolbar2QTAgg(
                qmc, self.main_widget)
            # pack these widget into the vertical box
            vbl.addWidget(qmc)
            vbl.addWidget(ntb)
            # # set the focus on the main widget
            # self.tab_widget.setFocus()
            # set the central widget of MainWindow to main_widget
            self.setCentralWidget(self.tab_widget)

def draw():
    figs = []

    # Standard Matplotlib code to generate the plot
    fig = matplotlib.pyplot.figure()
    axes = fig.add_subplot(111)
    x = numpy.arange(0.0, 3.0, 0.01)
    y = numpy.cos(1*numpy.pi*x)
    axes.plot(x, y)
    figs.append((fig,"tab 1"))

    fig = matplotlib.pyplot.figure()
    axes = fig.add_subplot(111)
    x = numpy.arange(0.0, 3.0, 0.01)
    y = numpy.cos(2*numpy.pi*x)
    axes.plot(x, y)
    figs.append((fig,"tab 2"))

    fig = matplotlib.pyplot.figure()
    axes = fig.add_subplot(111)
    x = numpy.arange(0.0, 3.0, 0.01)
    y = numpy.cos(3*numpy.pi*x)
    axes.plot(x, y)
    figs.append((fig,"tab 3"))

    return figs

# Create the GUI application
qApp = PyQt4.QtGui.QApplication(sys.argv)

figs = draw()

# Create the Matplotlib widget
mpl = ApplicationWindow(figs)
# show the widget
mpl.show()

# start the Qt main loop execution, exiting from this script
# with the same return code of Qt application
sys.exit(qApp.exec_())

個々のfigに対して画像ファイルとして保存するには、

fig.savefig(filename, dpi=300, transparent=True)
とかすると良い。実はこのあたり結構悩んだ。

複数タブに貼り付ける様にしているのは、任意数の複数グラフを同時表示できるようにしたかったのだけど、貼り付けたいグラフが結構メモリを消費してしまうため、結局のところ必要な分を一辺に貼り付けるのは無理だった。

月曜日, 10月 04, 2010

叔父が死去した

どうも先週の週末前だったらしい、が連絡が不明瞭でよく判らない。

とりあえず告別式に参加するために明日帰省する事にした。

玄関で雪崩が起きた

忙しさにかまけて古新聞を整理も処分もせずに玄関に放置していたら、表層雪崩が起きてしまった。家に着いて玄関口で一瞬途方に暮れてみたが、事故に伴い不幸にもトイレへの現在唯一の動線が遮断されてしまった。しかも帰宅の途中で尿意に襲われ、急ぎ帰宅した矢先にその状況を目にし、激しく焦燥感に苛まされることなった。最低限の動線確保をなさぬ限り、タイムリミットを設けられたこの状況を回復する事は困難であると思われた。

まずは多少の汚れや汗が問題にならぬ様下着姿となり、当面邪魔にならない場所に新聞紙を積み上げる最低限の場所を確保し埃を拭い払って、足下にある新聞紙を丁寧に広げながら一部づつ積み上げを開始した。崩れた新聞紙の総量は見かけ以上にあり、気付いたら新聞紙は自分の胸下辺りまで達する事となった。

とりあえずはトイレまでの動線は確保され、無事に用を足す事ができた。ただ、雪崩が起きる程の量の新聞が現在もなお玄関先に鎮座し続けている事を鑑みるに、問題の根本的な解決には全く達してはいない事は明白である。この事実を明示的に提示すべく、現在も状況の復旧作業はあえて不完全なままに保持する事とした。可及的速やかに時間を見つけ、状況の回復に向けて現実的な行動を行わなければならない。

状況は現在も切迫している。