matplotlibのグラフをインタラクティブなまま保存する

savefig() で画像に保存しちゃうと、矩形拡大とかができないし、
show() しちゃうと閉じたら消える。インタラクティブなまま保存できたらよいのにと思って調べてみた。

https://stackoverflow.com/questions/4348733/saving-interactive-matplotlib-figures
https://stackoverflow.com/questions/29160177/matplotlib-save-file-to-be-reedited-later-in-ipython

MATLABにはそういう機能が既にあるみたいですね。まぁ欲しくなるよね。
matplotlibの場合、figureオブジェクトをpickleで保存すればいいみたいです。

日本語でも情報ありました。このエントリを書く意味がほとんど無くなってしまった。
http://kuroneko0208.hatenablog.com/entry/2014/07/28/161453

バッチファイルを作っておいて、pickleファイルを放り込めばすぐに見れる、みたいな感じにしておけばいいのかなー。
pngでもpickleでも保存しておいて、中身を詳しく見たくなったらインタラクティブモードでも見れるみたいな形にしておくと便利かな

保存する側

#! /usr/bin/python2.7
# coding: utf-8

import matplotlib.pyplot as plt
import pickle

xs = range(10)
ys = [x**2 for x in xs]

fig = plt.figure()
ax = fig.add_subplot(111)

ax.plot(xs, ys)

#plt.show()

with open('figure_image.pkl', 'wb') as ofs:
    pickle.dump(fig, ofs)

表示する側

#! /usr/bin/python2.7
# coding: utf-8

import matplotlib.pyplot as plt
import pickle
import sys

filename = 'figure_image.pkl'
if len(sys.argv) > 1:
    filename = sys.argv[1]

with open(filename) as ifs:
    fig = pickle.load(ifs)
    plt.show()
rem plt_viewer.bat
cd %~dp0

python plt_viewer.py %1

pickleファイルをドラッグ&ドロップで放り込むと、グラフをpickleでリストアして表示する。

SeleniumのChromeDriverを自動更新するbashスクリプト

Seleniumの処理でエラーが出てから、chromeのwebdriverが更新されていることに気がついてファイルを置き換える、というのを何度も繰り返してウンザリしていたので自動化することにしました。
スクリプトをcron等に仕掛けておけば、常に最新のchromedriverが起動されるようにできます。

前提となるディレクトリ構成


/home/username/bin/ ... ユーザーusernameのホームディレクトリ配下のbin。あらかじめ作成しておく。
selenium-chromedriver/ ... chromedriverの各バージョンを保持するディレクトリ。あらかじめ作成しておく。
2.27/ ... chromedriverのバージョン。自動で作成される。
chromedriver ... chromedriverの実行可能ファイル。自動で作成される。
2.28/
chromedriver
X.XX/
chromedriver
chromedriver ... 最新のchromedriverバイナリへのシンボリックリンク。自動で作成・更新される。

Python2/3でgmailからメールを送信する(gmailライブラリ使用編)

エントリPython2.7でGMailから日本語メールを送信するではテキストメールを送れるスクリプトを書きましたが、HTMLメールだとか添付ファイルはつけられないので、すぐに不満がでてくると思います。というか出てきました。手元では都度少しづつ改造して使っていますが、ライブラリを使うのが効率が良いと思います。

ということで、PyPIを"gmail"で検索して一番に出てくるライブラリを使ってみました。gmailという名前です。直球ですね。

インストール方法

pip install gmail
続きを読む

Pythonでpickleを使って永続化する、期限付きメモ化デコレータ

止まっちゃうプログラムの応急処理として、pickleでキャッシュを永続化するメモ化関数を書いたのでついでにgistにあげました。いつかまた使う気がする。
メモ化する関数がコールバック関数を受け取るタイプの関数だったので、キャッシュのキーを作る段階で関数名の文字列に置き換えちゃってます。

windowsでxargs -Pがしたい

windowsでxargs -P 10 -n 2みたいなことをしたかったのですが、

  • powershellとかではそういうことができなさそう
  • cygwinは入れたくない

ということで自分で実装することにしました。
最低限必要な-P(--max-procs) -n(--max-args) {}(プレースホルダ)は実装されてます。

これで並列実行させることで7分掛かってた処理が3分になりました。
multiprocessingは本当に便利。

続きを読む

python pipでインストール用ファイルをローカルに保存しておく

アプリケーションを別のサーバーに載せ替えたい等の理由で、インストールされているpythonパッケージを、別のマシンへ展開したいことがあります。
こういう時pipなら、pip freezeでパッケージ名とバージョンの一覧を出力して、他マシンでその一覧を元にinstallすると簡単です。

[HOST A]$ pip freeze > /nas/pip/requirements.txt
[HOST A]$ cat /nas/pip/requirements.txt
BeautifulSoup==3.2.1
Flask==0.10.1
Jinja2==2.7.3
...
terminado==0.5
toolz==0.7.1
tornado==4.1
wheel==0.24.0
[HOST B]$ pip install -r /nas/pip/requirements.txt

しかし、これだとfreezeで一覧にした後に、ライブラリの特定のバージョンが公開停止されたり、あるいはライブラリ自体が
公開停止されると、うまく展開できなくなるか、一部の機能が動かない(とか、変に動いたりする)はず。

それだと困るので、今の状態で、予め依存するライブラリも含め、全てローカルに保存しておきたい。
しかしPyPIから一つ一つ落としてくるのも手間です。



こういうときに便利なコマンドは無いのか…



installコマンドに--downloadというオプションがありました。

指定すると、インストール用の.tar.gzや.whlファイルをフォルダに放り込んでくれます。
ダウンロードまでで、インストールはされません。これで今あるpython環境をローカルに落としておけます。

[HOST A]$ pip freeze > /nas/pip/requirements.txt
[HOST A]$ pip install --download /nas/pip/archive -r /nas/pip/requirements.txt

あとは展開される側でそのフォルダを参照してpip installすればOKです。

[HOST B]$ pip install --no-index --find-links=file:///nas/pip/archive -r /nas/pip/requirements.txt
...()
Collecting wheel==0.24.0 (from -r ..\requirements.txt (line 34))
Installing collected packages: pyquery, pytz, pyzmq, redis, requests, selenium,
tornado, terminado, toolz, wheel
  Running setup.py install for pyquery
  Running setup.py install for redis
  Running setup.py install for selenium
  Running setup.py install for tornado
  Running setup.py install for terminado
  Running setup.py install for toolz
Successfully installed pyquery-1.2.9 pytz-2014.10 pyzmq-14.6.0 redis-2.10.3 requests-2.5.1 selenium-2.44.0 terminado-0.5 toolz-0.7.1 tornado-4.1 wheel-0.24.0

なお、cx_OracleとかscipyとかpylzmaとかのC拡張が含まれる場合は、関連するコンパイラなども持っておく必要がある気がします。
あと、pip以外からパッケージをインストールしている場合(aptとかyumで入れてる場合)、当然これでは展開できないので要注意です。

※pip 1.5.6(python2.7)で動作確認してます。

参考:
User Guide − pip 6.1.1 documentation
How to use Python's pip to download and keep the zipped files for a package? - Stack Overflow

Project Eulerの日本語訳へのリンクを張るuser script(2015/4/30時点)

Project Eulerの日本語訳へのリンクを張るuser scriptを更新しました。

Chrome 42.0.2311.90 m
Tampermonkey 3.10.84
で動作確認してます。


// ==UserScript==
// @name         ScriptEuler
// @namespace    http://d.hatena.ne.jp/yatt/
// @description  link euler project problem to http://odz.sakura.ne.jp/
// @include      https://projecteuler.net/archives*
// ==/UserScript==

(function(){
  var lst = document.getElementsByClassName('id_column')
  var prefix = 'http://odz.sakura.ne.jp/projecteuler/index.php?cmd=read&page=Problem%20'
  
  for (var i = 1 ; i < lst.length; i++)
  {
      var no = lst[i].innerHTML
      var a = document.createElement('a')
      a.href = prefix + no
      a.innerText = no
      
      lst[i].innerText = ''
      lst[i].appendChild(a)
  }
})()


関連