ナンクル力学系

学んだ事を書き連ねていこう。

Posts Tagged ‘gnuplot

Gnuplot.py で頑張って pm3d map を使う方法

leave a comment »

Gnuplot.py に入っているオプションは,matrixを受け付けてくれないので ちょっとした(?)ハックが必要だった.かなり試行錯誤したけど.

ソース:

import Gnuplot
import numpy

gnp = Gnuplot.Gnuplot(debug=1)

def plot_mat(mat0):
    # 端の行と列がなくなってしまうので,ダミーを入れる
    (x,y) = mat0.shape
    mat1 = numpy.zeros((x+1, y+1))
    mat1[:x,:y] = mat0
    # splot に 'matrix' オプションを加えるためのhack
    # /usr/lib/python2.5/site-packages/Gnuplot/PlotItems.py を読んだ
    plot = Gnuplot.PlotItems.Data(mat1, using='($2):($1):($3)')
    if plot._option_sequence[0] != 'matrix':
        plot._option_sequence.insert(0,'matrix')
    plot._options['matrix'] = (None,"matrix")
    # plot
    gnp('set pm3d map corners2color c1')
    gnp('set xrange [*:*] reverse')
    gnp.splot(plot)
    gnp('unset pm3d')
    gnp('set xrange [*:*] noreverse')

plot_mat(
    numpy.array([[0, 0  , 0  , 0  , 1],
                 [0, 0.4, 0.1, 0.0, 0],
                 [0, 1.0, 0.6, 0.1, 0],
                 [0, 0.1, 1.0, 0.8, 0],
                 [0, 0  , 0  , 0  , 0]])
    )

実行結果

Written by tkf

April 18, 2009 at 10:48 pm

Posted in 研究日誌

Tagged with ,

卒論の時に活躍した自作のジェネレータ

leave a comment »

gnuplotのファイルとか,TeXの表とか,繰り返しが多いテキストの生成をやらないと いけない場面が多かったので,作ってみた. jinja っていう python製テンプレートエンジンを使っていて, 自作した部分はコマンドの引数処理くらいだけど. gnuplotのジェネレータを何回も作るよりかなり効率が良くなったので公開. 他にもこういうツールあるんだろうか.

作ったプログラムはこんな感じ:

  • jinja で書いたテンプレートにデータを流し込む
  • 大きなデータは yaml に入れる
  • コマンドオプションからも,データ入れられる
  • コマンド引数にとったファイル名もデータとして使える
yaml_and_jinja_to_anything.py
import jinja
import os
import codecs
import yaml
import re

re_coding = re.compile('coding *: *(.+)[ \n]')
def guess_encoding(string, default='utf-8' ):
    _re_coding = re_coding
    import re
    try: # to estimate coding
        encoding = _re_coding.search(string).group(1)
    except AttributeError:
        encoding = default
    return encoding

from optparse import OptionParser
parser = OptionParser()
parser.add_option(
    "-y", "--yaml", dest="yfile",
    default=None, metavar="FILE", help="yaml file.")
parser.add_option(
    "-j", "--jinja", dest="jfile",
    help="jinja file.", metavar="FILE")
parser.add_option(
    "-f", "--flags", dest="flag",
    default=None, metavar="FLAG", help="ex) -f name1:flag1,name2:flag2")
parser.add_option(
    "-i", "--jinja_coding", dest="jcoding",
    default=None, metavar="CODING",
    help="coding of jinja file. try to estimate if not specified." )
parser.add_option(
    "-d", "--out_file", dest="ofile",
    default=None, metavar="CODING",
    help=("output file name. if yaml has more than one data, "
          "the file name has suffix.") )
parser.add_option(
    "-o", "--out_coding", dest="ocoding",
    default=None, metavar="CODING",
    help="coding of output file." )

(opts, args) = parser.parse_args()

jstr_unknown = open(opts.jfile, 'rb').read()
if opts.jcoding is not None:
    jcoding = opts.jcoding
else:
    jcoding = guess_encoding(jstr_unknown)
jstr = unicode( jstr_unknown, jcoding )

env = jinja.Environment()
tmp = env.from_string( jstr )

if opts.yfile is not None:
    yaml_data = yaml.load( file(opts.yfile) )
else:
    yaml_data = None

if opts.ofile is None:
    def write_out(string):
        import sys
        codecs.getwriter('utf-8')(sys.stdout).write(string)
else:
    def write_out(string):
        ## print "outfile: ", outfile
        if opts.ocoding is not None:
            ocoding = opts.ocoding
        else:
            ocoding = guess_encoding(string)
        ## print "  coding: ", ocoding
        codecs.open(opts.ofile, 'w', ocoding).write(string)

if opts.flag is not None:
    flag = dict( [ [i.strip() for i in nf.split(":")] 
                   for nf in opts.flag.split(",")
                   ] )
else:
    flag = None

data = dict(
    arg = args,
    flg = flag,
    yml = yaml_data
    )
write_out( tmp.render(data) )

if opts.ofile is None:
    print

このファイルを,”ln-s yaml_and_jinja_to_anything.py yj2a” と して,”yj2a”から実行出きるようにした.

gnuplotのファイルを生成してみる

sin.jin.gnuplot
{% if flg.out == "x11" -%}
  set term x11
{% else %}
  set term png
  set size {{ yml.xsize }}, {{ yml.ysize }}
{% endif %}
{{ yml.options }}

{% if flg.out == "x11" -%}
  set term x11 {{ loop.index0 }}
{% else %}
  set out '{{ yml.imgname }}.png'
{% endif -%}
set multiplot
set size {{ yml.xsize }}, {{ yml.ysize_each }}

{% for p in yml.plot -%}
  set origin {{ p.origin }}
  set xlabel '{{ p.xlabel }}'
  set ylabel '{{ p.ylabel }}'
  plot [-3:3][-1.1:1.1]\
    {%- for l in p.line %}
      {{ l }}
      {%- if not loop.last %},\{% endif -%}
    {% endfor %}
{% endfor -%}
unset multiplot
sin.yml
imgname: sin

xsize: 0.9
ysize: 0.9
ysize_each: 0.45

plot:
  - origin: 0,0
    xlabel: 'x'
    ylabel: 'Sin(n*x)'
    line:
      - 'sin(x)'
      - 'sin(2*x)'
      - 'sin(3*x)'
      - 'sin(3*x)'
      - 'sin(4*x)'
      - 'sin(5*x)'
      - 'sin(6*x)'
      - 'sin(7*x)'
  - origin: 0,0.45
    xlabel: 'x'
    ylabel: 'x**n'
    line:
      - 'x'
      - 'x**2'
      - 'x**3'
      - 'x**4'
      - 'x**5'
      - 'x**6'
      - 'x**7'
      - 'x**8'
実行結果(yj2a -f out:x11 -y sin.yml -j sin.jin.gnuplot)
set term x11

set term x11 
set multiplot
set size 0.9, 0.45

set origin 0,0
  set xlabel 'x'
  set ylabel 'Sin(n*x)'
  plot [-3:3][-1.1:1.1]\
      sin(x),\
      sin(2*x),\
      sin(3*x),\
      sin(3*x),\
      sin(4*x),\
      sin(5*x),\
      sin(6*x),\
      sin(7*x)
set origin 0,0.45
  set xlabel 'x'
  set ylabel 'x**n'
  plot [-3:3][-1.1:1.1]\
      x,\
      x**2,\
      x**3,\
      x**4,\
      x**5,\
      x**6,\
      x**7,\
      x**8
unset multiplot

gnuplotの中で “load ‘< yj2a -f out:x11 -y sin.yml -j sin.jin.gnuplot'” と実行すると,Xにグラフが出力されて, “load ‘< yj2a -y sin.yml -j sin.jin.gnuplot'” と実行すると,sin.pngが作られる:

データを変えて,別のyamlを作ってみる

sin2.yml
imgname: sin2

xsize: 0.9
ysize: 0.9
ysize_each: 0.45

plot:
  - origin: 0,0
    xlabel: 'x'
    ylabel: 'x*Sin(n*x)'
    line:
      - 'x*sin(x)'
      - 'x*sin(2*x)'
      - 'x*sin(3*x)'
      - 'x*sin(3*x)'
      - 'x*sin(4*x)'
      - 'x*sin(5*x)'
      - 'x*sin(6*x)'
      - 'x*sin(7*x)'
  - origin: 0,0.45
    xlabel: 'x'
    ylabel: 'Cos(x**n)'
    line:
      - 'cos(x)'
      - 'cos(x**2)'
      - 'cos(x**3)'
      - 'cos(x**4)'
実行結果

yamlを入れ変えるだけで色々なデータに対応できるし, コマンドオプションでXに出すかpngに出すかも切り替えられて便利!

Written by tkf

February 11, 2009 at 12:13 am

Posted in 研究日誌, PC

Tagged with , ,

sshログインなどでX windowが使えない環境でgnuplotを使う方法

leave a comment »

gnuplot-dumb

家に居て,ラボにsshで接続して,gnuplotでグラフ書こうと思ったらX飛んでこなかった.これは大変!

そんな時,「グラフをテキストで出力する」という記事を思い出したので早速,

set term dumb

し,グラフの出力先をテキストに.無事グラフが見れた:

gnuplot-dumb

大体の感じはつかめる...よね?w

まあ,正確なグラフ欲しかったらpngに吐いてダウンロードするか,そもそもデータファイルをダウンロードすべきだよね.(ぉ

研究忙しいからブログに逃げてるわけではないんだから!

Written by tkf

November 15, 2008 at 10:22 pm

Posted in PC

Tagged with

gnuplotでカラーマップ(?)

leave a comment »

Screenshot-Gnuplot (window id : 0), originally uploaded by takafumi_a.

沢山の時系列データ・マトリックスの成分を確認したいとき、カラーマップ(ってのが正しい名前か謎だけど)をgnuplotでプロットする方法。

gnuplot> set pm3d map
gnuplot> splot [xmin:xmax][ymin:ymax][zmin:zmax]ファイル名‘ matrix using xaxis:yaxis:($3)

でOK

[xmin:xmax][ymin:ymax][zmin:zmax]にはx,y,z軸の最大・最小値を入れる。省略しても良い。例えば[][][0:1]ならx,y軸は勝手に決めてくれてそれぞれの要素数になり、z軸(カラーマップ)の最大・最小が[0:1]となる。

xaxis:yaxis:($3)には{($1),($2)}を入れる。例えばusing ($2):($1):($3)なら転置で、using ($1):($2):($3)ならデフォルトと同じなので省略して良い。

参考:

Written by tkf

November 4, 2008 at 4:59 pm

Posted in PC

Tagged with