# -*- coding: utf-8 -*- import pylab from math import radians, sin, cos, tan def make_bezier(p0, p1, p2, p3): # ベジエ曲線の公式 # t: 0.0~1.0までの値 0.0のとき、始点をplotし、1.0のとき、終点をplotする。 def formula(t, p0, p1, p2, p3): return ((1-t)**3)*p0 + (3*t)*((1-t)**2)*p1 + 3*(t**2)*(1-t)*p2 +(t**3)*p3 def _bezier(t): return [formula(t, p0[i],p1[i],p2[i],p3[i]) for i in (0, 1)] return _bezier def transform(x, y, m): return (x*m[0] + y*m[3] + m[6], \ x*m[1] + y*m[4] + m[7], \ x*m[2] + y*m[5] + m[8]) if __name__ == '__main__': t = pylab.arange(0.0, 1.001, 0.01) bazier = make_bezier((0, 0), (0, 3), (3, 0), (3, 3)) # 変換なし m = (1, 0, 0, \ 0, 1, 0, \ 0, 0, 1) coordinates = [(x, y) for x, y, z in (transform(x, y, m) for x, y in zip(*bazier(t)))] (xs,ys) = zip(*coordinates) pylab.plot(xs, ys) # 平行移動 (3, 3) m = (1, 0, 0, \ 0, 1, 0, \ 3, 3, 1) coordinates = [(x, y) for x, y, z in (transform(x, y, m) for x, y in zip(*bazier(t)))] (xs,ys) = zip(*coordinates) pylab.plot(xs, ys) # 拡大 (-1.5, -1.5) ※原点対照に反転し、1.5培する。 m = (-1.5, 0, 0, \ 0, -1.5, 0, \ 0, 0, 1) coordinates = [(x, y) for x, y, z in (transform(x, y, m) for x, y in zip(*bazier(t)))] (xs,ys) = zip(*coordinates) pylab.plot(xs, ys) # 回転 60° r = radians(60) m = (cos(r), sin(r), 0, \ -sin(r), cos(r), 0, \ -5, 5, 1) coordinates = [(x, y) for x, y, z in (transform(x, y, m) for x, y in zip(*bazier(t)))] (xs,ys) = zip(*coordinates) pylab.plot(xs, ys) # 傾斜 a=15° b=20° a = radians(-15) b = radians(-20) m = (1, tan(a), 0, \ tan(b), 1, 0, \ -5, 5, 1) coordinates = [(x, y) for x, y, z in (transform(x, y, m) for x, y in zip(*bazier(t)))] (xs,ys) = zip(*coordinates) pylab.plot(xs, ys) pylab.grid() pylab.axis([-15, 15, -15, 15]) pylab.show()
2012年5月17日木曜日
[Python, pylab]how to transform graphics with 3-by-3 transformation matrix.
pylabでベジエ曲線が描けたので、今度は変換行列で、変換を行ってみます。
2012年5月16日水曜日
[Python,pylab]how to plot bezier curve.
pylabの実験のために、ベジエ曲線を描いてみました。
ベジエ曲線を描くためのメソッドを使用するのではなく、
数式で座標を計算してプロットしました。
>>> import pylab >>> def bezier(p0, p1, p2, p3): def f(t, p0, p1, p2, p3): return ((1-t)**3)*p0 + (3*t)*((1-t)**2)*p1 + 3*(t**2)*(1-t)*p2 +(t**3)*p3 def _bezier(t): return [f(t, p0[i],p1[i],p2[i],p3[i]) for i in (0, 1)] return _bezier >>> t = pylab.arange(0.0, 1.0, 0.01) >>> f = bezier((2, 2), (3, 4), (4.5, 4), (5, 1.5)) >>> pylab.plot(*f(t)) >>> pylab.axis([0, 6, 0, 6]) >>> pylab.show()確かにベジエ曲線が描けました。
ラベル:
bezier curve,
plot,
pylab,
python,
ベジエ
2012年3月8日木曜日
python mapserver-6.0.2 mapscript layerObj NameError
MapServerの調査をしています。
SWIG MapScript APIのpython版にバグがあるようです。
以下のようなコードを書くと、例外が発生します。
>>>import mapscript >>>map = mapscript.mapObj('./x.map') >>>layer = mapscript.layerObj(map) Traceback (most recent call last): File "mapscript.pyをのぞいてみると、確かに"args"という変数は未定義です。", line 1, in File "/usr/local/lib/python2.7/site-packages/MapScript-6.0.2-py2.7-linux-x86_64.egg/mapscript.py", line 1381, in __init__ if args and len(args)!=0: NameError: global name 'args' is not defined
class layerObj(_object): __swig_setmethods__ = {} __setattr__ = lambda self, name, value: _swig_setattr(self, layerObj, name, value) __swig_getmethods__ = {} # 略 def __init__(self, map = None): this = _mapscript.new_layerObj(map) try: self.this.append(this) except: self.this = this if 1: if args and len(args)!=0: #'args' is not defined! self.p_map=args[0] else: self.p_map=None # 略しょうがないので、以下のように修正し、python-mapscriptをインストールしなおしました。
class layerObj(_object): __swig_setmethods__ = {} __setattr__ = lambda self, name, value: _swig_setattr(self, layerObj, name, value) __swig_getmethods__ = {} # 略 def __init__(self, map = None): this = _mapscript.new_layerObj(map) try: self.this.append(this) except: self.this = this #if 1: # if args and len(args)!=0: #'args' is not defined! # self.p_map=args[0] # else: # self.p_map=None self.p_map = map # 略これで一応動きました。 追記: classObjのコンストラクターも同様に修正が必要でした。 あと、既知のバグみたいです。 MapServer Issue Tracker "MapScript classObj Error" http://trac.osgeo.org/mapserver/ticket/3940
2012年2月23日木曜日
easy_install bad interpreter
pythonでモジュールのインストールに使う、“easy_install”をインストールして使おうとしたところ、
↓こんなエラーがでました。
$ sudo easy_install
-bash: /usr/local/bin/easy_install: .: bad interpreter: Permission denied
shebang(シェルスクリプトの1行目の#!で始まる行)を確認すると
#!.
# EASY-INSTALL-ENTRY-SCRIPT: 'setuptools==0.6c11','console_scripts','easy_install'
__requires__ = 'setuptools==0.6c11'
import sys
from pkg_resources import load_entry_point
と、#!.になっていたので、pythonの実行ファイルのパスを指定したらエラーが起こらなくなりました。
$ sudo easy_install
error: No urls, filenames, or requirements specified (see --help)
なぜ、shebangがそんな風になっていたのか、原因は調べていません。
↓こんなエラーがでました。
$ sudo easy_install
-bash: /usr/local/bin/easy_install: .: bad interpreter: Permission denied
shebang(シェルスクリプトの1行目の#!で始まる行)を確認すると
#!.
# EASY-INSTALL-ENTRY-SCRIPT: 'setuptools==0.6c11','console_scripts','easy_install'
__requires__ = 'setuptools==0.6c11'
import sys
from pkg_resources import load_entry_point
と、#!.になっていたので、pythonの実行ファイルのパスを指定したらエラーが起こらなくなりました。
$ sudo easy_install
error: No urls, filenames, or requirements specified (see --help)
なぜ、shebangがそんな風になっていたのか、原因は調べていません。
2012年2月21日火曜日
mysql-python MySQLdb ImportError: libmysqlclient_r.so.15
mysql-python(MySQLdb)をインストールして、以下のエラーが発生した場合、
共有オブジェクトにパスが通ってないのかもしれません。
その場合、ldconfigを使用して、当該shared objectにパスを通すと、動くようになります。
$ python
>>> import MySQLdb
Traceback (most recent call last):
File "", line 1, in
File "build/bdist.linux-i686/egg/MySQLdb/__init__.py", line 19, in
File "build/bdist.linux-i686/egg/_mysql.py", line 7, in
File "build/bdist.linux-i686/egg/_mysql.py", line 6, in __bootstrap__
ImportError: libmysqlclient_r.so.15: cannot open shared object file: No such file or directory
>>>
$ sudo vi /etc/ld.so.conf
Include ld.so.conf.d/*.conf
/usr/local/lib
/usr/lib/mysql ←これを追加。
$ sudo ldconfig
$ python
>>> import MySQLdb
>>>
共有オブジェクトにパスが通ってないのかもしれません。
その場合、ldconfigを使用して、当該shared objectにパスを通すと、動くようになります。
$ python
>>> import MySQLdb
Traceback (most recent call last):
File "
File "build/bdist.linux-i686/egg/MySQLdb/__init__.py", line 19, in
File "build/bdist.linux-i686/egg/_mysql.py", line 7, in
File "build/bdist.linux-i686/egg/_mysql.py", line 6, in __bootstrap__
ImportError: libmysqlclient_r.so.15: cannot open shared object file: No such file or directory
>>>
$ sudo vi /etc/ld.so.conf
Include ld.so.conf.d/*.conf
/usr/local/lib
/usr/lib/mysql ←これを追加。
$ sudo ldconfig
$ python
>>> import MySQLdb
>>>
2012年1月19日木曜日
python MySQLdb で取得したデータを Jinja2でrenderすると UnicodeDecodeError
MySQLから取得したデータをJinja2を使って出力する場合、
MySQLdbモジュールのconnect関数でConnectionオブジェクトを取得する際に、
use_unicodeとcharset引数を設定し、取得結果の文字列をunicodeで保持する必要があります。
API - Jinja2 2.7-dev documentation Unicode
http://jinja.pocoo.org/docs/api/#unicode
下記の記述があります。
訳:
MySQLdb User's Guide MySQLdb Functions and attributes
http://mysql-python.sourceforge.net/MySQLdb.html#functions-and-attributes
connect(parameters...)
use_unicode
charset
以下に実例を示します。
ASCII文字列ではない文字列を渡したので、UnicodeDecodeErrorが起きます。
言い換えると、文字列が渡されたときは、Unicodeに変換するために、x.decode('ascii')を試み、
結果、encodeがasciiでない場合は、UnicodeDecodeErrorが起きる。と言えそうです。
文字列はutf8でdecodeしてUnicodeで保持するように指示したので、
UnicodeDecodeErrorは起きません。
charset='utf-8'
にすると、例外が発生します。
***
上記はCentOS5.5で動作させた例なのですが、
同様のことをwindowsのeclipse/PyDevで行うと、
MySQLdb.connect関数でuse_unicode=Trueとしなくても、
UnicodeDecodeErrorは起きませんでした。
理由はわかりません。
MySQLdbモジュールのconnect関数でConnectionオブジェクトを取得する際に、
use_unicodeとcharset引数を設定し、取得結果の文字列をunicodeで保持する必要があります。
API - Jinja2 2.7-dev documentation Unicode
http://jinja.pocoo.org/docs/api/#unicode
下記の記述があります。
Jinja2 is using Unicode internally which means that you have to pass Unicode objects to the render function or bytestrings that only consist of ASCII characters.
訳:
Jinja2 の内部処理はUnicodeを使用しているので、render関数にはUnicodeオブジェクトかASCII文字のみからなるバイト文字列を渡す必要があります。
MySQLdb User's Guide MySQLdb Functions and attributes
http://mysql-python.sourceforge.net/MySQLdb.html#functions-and-attributes
connect(parameters...)
use_unicode
charset
以下に実例を示します。
$ python Python 2.7.1 (r271:86832, Nov 10 2011, 09:26:52) [GCC 4.1.2 20080704 (Red Hat 4.1.2-48)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import MySQLdb as db >>> import jinja2 as j2 >>> def get_rows_with(con): ... with con: ... cur = con.cursor() ... cur.execute("select * from test_table") ... rows = cur.fetchall() ... cur.close() ... return rows ... >>> t = j2.Template('{% for row in rows %}{{ row[0] }} | {{ row[1] }}\n{% endfor %}') >>> con = db.connect(host='localhost', db='test', user='test_user', passwd='xxxx') >>> rows = get_rows_with(con) >>> print t.render(rows=rows) Traceback (most recent call last): File "", line 1, in File "/usr/local/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/environment.py", line 894, in render return self.environment.handle_exception(exc_info, True) File "", line 1, in top-level template code UnicodeDecodeError: 'ascii' codec can't decode byte 0xe6 in position 0: ordinal not in range(128)
ASCII文字列ではない文字列を渡したので、UnicodeDecodeErrorが起きます。
言い換えると、文字列が渡されたときは、Unicodeに変換するために、x.decode('ascii')を試み、
結果、encodeがasciiでない場合は、UnicodeDecodeErrorが起きる。と言えそうです。
>>> con = db.connect(host='localhost', db='test', user='test_user', passwd='xxxx', use_unicode=True, charset='utf8') >>> rows = get_rows_with(con) >>> print t.render(rows=rows) 01 | あ 02 | い 03 | う 04 | え 05 | お
文字列はutf8でdecodeしてUnicodeで保持するように指示したので、
UnicodeDecodeErrorは起きません。
charset='utf-8'
にすると、例外が発生します。
***
上記はCentOS5.5で動作させた例なのですが、
同様のことをwindowsのeclipse/PyDevで行うと、
MySQLdb.connect関数でuse_unicode=Trueとしなくても、
UnicodeDecodeErrorは起きませんでした。
理由はわかりません。
2012年1月17日火曜日
mysql-python windows setup.py build
pythonがインストールされていて、MySQLサーバがインストールされていないマシンで、
mysql-pythonのMySQLdbモジュールを使いたいとき、
モジュールのセットアップには、Connector/Cが必要です。
【手順】
これで、ビルドする。
私の環境では、これで使えるようになりました。
mysql-pythonのMySQLdbモジュールを使いたいとき、
モジュールのセットアップには、Connector/Cが必要です。
【手順】
- Connector/Cをインストールする。
- MySQL-python-1.2.3.tar.gzをdownloadして展開する。
- setup_windows.pyのget_configの以下の部分を修正する。
metadata, options = get_metadata_and_options() # 以下2行をコメントアウトし、1行追加 #serverKey = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, options['registry_key']) #mysql_root, dummy = _winreg.QueryValueEx(serverKey,'Location') mysql_root = 'C:\\Program Files (x86)\\MySQL\\MySQL Connector C 6.0.2' # Connector/Cのインストール先
>python setup.py build
私の環境では、これで使えるようになりました。
登録:
投稿 (Atom)