ruby dcl メモ
サンプル
- 簡単なやつ
- 簡単なやつ (経度—緯度)
- 簡単なやつ (ベクトル)
- <URL:./scripts/mkfig_U.rb>
- <URL:./scripts/gphys_const_v1.2.rb>
- <URL:./scripts/gphys_methods_v2.00.rb>
リンク
gropn
iws = (ARGV[0] || (puts ' WORKSTATION ID (I) ? ;'; DCL::sgpwsn; gets)).to_i DCL.gropn(iws)
変数名
gphys.name = "variable name"
long_name
gphys.long_name = "long name"
units
gphys.units = "unit"
missing_value
欠損値確認
rmiss = gphys.get_att('missing_value')[0]
欠損値設定
DCL.glpset('lmiss',true) DCL.glpset('rmiss',rmiss)
color map
DCL.sgscmn(4) # blue-cyan-white-yellow-red DCL.sgscmn(5) # gray-scale DCL.sgscmn(14) # blue-white-red
see also here.
copy
gphyscopied = gphys.copy
グローバル属性/大域属性
gphys = GPhys::IO.open('....','hoge') val = file.att(name).get
name が属性名.
参考ページ
分割
DCL.sldiv('y',1,2)
<URL:http://ruby.gfd-dennou.org/products/ruby-dcl/ruby-dcl-doc/grph1/node24.html>
フレーム進行
DCL.sgfrm
<URL:http://ruby.gfd-dennou.org/products/ruby-dcl/ruby-dcl-doc/grph1/node24.html>
GPhys オブジェクト作成
非GPhysデータの書出し -- GPhysオブジェクトを一から作る
require "numru/gphys" include NumRu nlon = 36 nlat = 18 va_lon = VArray.new( NArray.sfloat(nlon).indgen(0,360.0/nlon), {"long_name"=>"longitude", "units"=>"degrees_east"}, "lon" ) ax_lon = Axis.new.set_pos(va_lon) va_lat = VArray.new( NArray.sfloat(nlat).indgen(0,180/nlat), {"long_name"=>"latitude","units"=>"degrees_north"}, "lat" ) ax_lat = Axis.new.set_pos(va_lat) va_data = VArray.new( NArray.sfloat(nlon,nlat).indgen, {"long_name"=>"temperature", "units"=>"K"}, "T" ) gphys = GPhys.new( Grid.new(ax_lon,ax_lat), va_data ) file = NetCDF.create("tmp.nc") GPhys::NetCDF_IO.write(file,gphys) file.close
欠損値追加
def addmissingvalue( gp ) ax_press = gp.axis('Press') nam_data = NArrayMiss.to_nam_no_dup(gp.val) nam_data.set_missing_value( $missing_value ) va_data = VArray.new( nam_data, {"long_name"=>gp.long_name, "units"=>gp.units.to_s}, gp.name ) gp = GPhys.new( Grid.new(ax_press), va_data ) return gp end
- 参考ページ
配列次元変更
2 次元から 3 次元
na_val = gp.val.reshape!(gp.shape[0],gp.shape[1],1)
軸
時間軸指定
tas = GPhys::IO.open("tas.nc","tas") tas.cut("time"=>DateTime.parse("20061202"))
軸情報取得・変換
z = gphys.axis(namelev).pos.convert_units( Units['Pa'] ) z.long_name = 'pressure' gphys.axis(namelev).set_pos(z) z = gphys.axis(namelev).pos.convert_units( Units['days since 1979-1-1 00:00:0.0'] ) gphys.axis(namelev).set_pos(z) time = gphys.coord('time').val ls = gphys.coord('ls').val ls = ls + 360 ls = ls % 360 varraytime = VArray.new( ls, { "long_name"=>'Ls', "units"=>'degree' }, "ls" ) gphys.axis('ls').set_pos(varraytime) km = gphyscopied.shape[1]
時間軸指定のための変換
Date.parse("2010-01-04")
軸の太さなど
#DCLExt.uz_set_params 'indext1'=>3,'indext2'=>5,'indexl1'=>5,'indexl2'=>5 DCLExt.uz_set_params 'indext1'=>9,'indext2'=>9,'indexl1'=>9,'indexl2'=>9
references:
緯度経度分布の時
GGraph.set_fig 'itr'=>10, 'viewport'=>[vpx1,vpx2,vpy1,vpy2], 'yrev'=>'units:Pa', 'window'=>[x1,x2,y1,y2] GGraph.set_map 'coast_world'=>false, 'grid'=>false GGraph.set_axes('xlabelint'=>90) GGraph.set_axes('ylabelint'=>30) ... GGraph.tone true, ... 'map_axes'=>true
配列サイズ情報
size = gphys.length shapearray = gphys.shape
mask
mask = gphys.val.get_mask k = 0 while k < km j = 0 while j < jm if mask[j,k] == 1 then gphysout[j,k] = ( RPlanet * cos( lat[j] * PI / 180.0 ) * Omega + gphysout.val[j,k] ) * RPlanet * cos( lat[j] * PI / 180.0 ) end j = j + 1 end k = k + 1 end
or
gphyszm[ (gphyszm.gt 1.0e3) ] = 1.0e3
(gphyszm.gt 1.0e3) が byte 型配列 (マスク) を作っている.
描画範囲クリップ
DCL.sgpset('lclip', true)
or
下のようにすると, ビューポートからはみ出した部分は描かれない.
DCL.sglset( 'LCLIP', true )
連続描画・動画
DCL::swlset('lwait', false) # wait or no wait DCL::swlset('lalt' , true ) # using backing store
legend
line(gphys, true, ..., 'legend'=>'xxx', 'legend_vx'=>0.2, ... )
文字
フォントの変更 1
環境変数を変える.
$ export SW_LSYSFNT=true $ export SW_FONTNAME="Helvetica"
ruby スクリプト内から実行するなら
ENV['SW_LSYSFNT'] = 'true' ENV['SW_FONTNAME'] = "Helvetica"
要するに環境変数を変える.
フォントの変更 2
DCL.sgiset('IFONT', 2) DCL.sgstxi(3)
see <URL:http://ruby.gfd-dennou.org/products/ruby-dcl/ruby-dcl-doc/rakuraku/node24.html>
サイズ
DCL.uzfact(0.75)
sgtxu/sgtxv で文字を書く時の文字サイズ
rsize = DCL.sgqtxs() DCL.sgstxs( rsize*0.25 ) DCL.sgstxc(1) DCL.sgtxu( lone, late+(late-lats)*0.05, label ) or DCL.sgtxv( 0.85, 0.56, label ) DCL.sgstxc(0) DCL.sgstxs( rsize ) DCL.sglset('LCLIP', true)
sgtxu/sgtxv で文字を書く時の文字インデクス
iindex = DCL.sgqtxi() DCL.sgstxi(3) DCL.sgstxi(iindex)
<URL:http://dennou-q.geo.kyushu-u.ac.jp/arch/dcl/dcl-f77doc/rc1/grph1/node67.html>
図のシンボル (a), (b), ...
# panel symbol (a), (b), ... icharnum = "a".ord - 1 icharnum += 1 label = "("+icharnum.chr+")" rsize = DCL.sgqtxs() iind = DCL.sgqtxi() DCL.sgstxs( rsize*0.5 ) DCL.sgstxi(3) DCL.sgstxc(-1) DCL.sglset('LCLIP', false) DCL.sgtxv( vpx1, vpy2*1.05, label ) DCL.sglset('LCLIP', true) DCL.sgstxi(iind) DCL.sgstxs( rsize )
上付き・下付き
DCL.sglset('LCNTL', true)
| または _ で始めて " が終了の記号. " は必須.
DCL.ussttl( 'wavenumber', 'cm|-1"', 'up.flux', 'Wm|-2"(cm|-1")|-1"' )
特殊文字とか
× --- DCL::csgi(194) # "x" (multiply)
<URL:https://www.gfd-dennou.org/library/dcl/dcl-f90/doc/table/font.htm>
<URL:http://133.5.166.3/library/dcl/dcl-f77doc/doc_numaguti/rakuraku/append/append.html#フォント一覧>
<URL:http://ruby.gfd-dennou.org/products/ruby-dcl/ruby-dcl-doc/rakuraku/node24.html>
文字書き関係
- sgtxu, sgtxv, sgtxrで描く文字列のセンタリングオプションの設定
- sgtxu, sgtxv, sgtxrで描く文字列の回転角の設定
- sgtxu, sgtxv, sgtxrで描く文字の高さの設定
- sgtxu, sgtxv, sgtxrで描く文字のラインインデクスの設定
参考
ruby-DCL で線・点を描く
DCL::uuslnt(2) # 線のタイプ DCL::uuslni(21) # 線のインデクス DCL::uulin(a_lon, a_lat) # 線を引く #DCL::uusmks(0.015) # マークのサイズ DCL::uusmki(25) # マークの線の太さ DCL::uusmkt(2) # マークの種類 DCL::uumrk(a_lon, a_lat) # マークを描く
複数に分かれたファイルの読み込み
vname = "GMQH2OVap" # case 1 ncfn = "????/Temp_rank??????.nc" url = ncfn + "@" + vname gphys = GPhys::IO.open_gturl( url ) # case 2 fns = 3 fne = 6 path = Array.new(fne-fns+1) for i in fns..fne do path[i-fns] = "data/GMQH2OVap_rank" + i.to_s.rjust(6,'0') + ".nc" end p path gphys = GPhys::NetCDF_IO.open( path, vname ) # case 3 path = /data\/GMQH2OVap_rank(\d\d\d\d\d\d).nc/ p path gphys = GPhys::NetCDF_IO.open( path, vname )
複数に分かれたファイルの読み込み (gpview)
$ gpview U_rank00000\?.nc@U --mean lon
画像ファイル名
下のようにすると, 出力ファイル名は file.pdf となる.
DCL.swcset( 'FNAME', 'file' )
画像フォーマット変更
iws=2 DCL.swpset("ifl",1) DCL.gropn(iws)
'ifl' は出力するファイルフォーマット番号で, 1:png,2:eps,3:SVG,4:PDF. 初期値は 4 です.
(GRPH1 のマニュアル http://www.gfd-dennou.org/arch/dcl/pdf/grph1.pdf の 103 ページ(SWPACK) のサブルーチン使用します.)
連続ページ描画
DCL.swpset("lwait", false) DCL.swpset("lalt" , true )
lwait は, 改ページのタイミングで一時停止するかどうか, lalt は裏画面で描画するかどうかの指定らしい.
<URL:http://ruby.gfd-dennou.org/products/ruby-dcl/ruby-dcl-doc/grph1/node176.html>
等値線 (コンター) メッセージ
DCL.udlset('LMSG', false)
<URL:http://ruby.gfd-dennou.org/products/ruby-dcl/ruby-dcl-doc/rakuraku/node52.html>
サイズの大きな 2 時元データの描画
- GGraph.tone には, "auto", "tonf" 等のオプションがある.
- "auto"=>false, "tonf"=>true とすることで, uetonf を使って描画する
- tone はデータサイズに制限がある.
- tonf ならば描ける
- ただし, ggraph.rb 内の l.2777 辺りの uwsgya (uwsgxa) を コメントアウトする必要があるようだ
- contour はデータサイズに制限がある
tone 覚書 (この問題は解決したのかも)
GGraph.tone には, "auto"=>false のオプションを付けておく方が良い.
GGraph.tone のオプション "auto"=>true (デフォルト) の場合, 与える配列サイズが大きいと, 自動的に uetonf を使って描画される. 現状, uetonf を使って, itr=10 などで描画すると, 枠が描かれてしまう (GGraph.set_map('vpt_boundary'=>true) としていたとしても). 原因は不明.
とりあえず, "auto"=>false として, uetone で描画することにより, (GGraph.set_map('vpt_boundary'=>true) としておけば) 枠が描かれない.
線の色
DCL.uuslni(XXXX)
XXXX の十の位の数字で指定
確認.
lidx = DCL.uuqlni()
複数の図の配置
軸ラベルの詳細設定
GGraph.set_axes('xlabelint'=>90) GGraph.set_axes('ylabelint'=>30)
正負の値があるときの対数グラフ
1 つの図に複数の線を描く場合. (gp を GPhys オブジェクトの配列にする. 配列でなくても動く.)
def line_x_log( itr, svx1, svx2, svy1, svy2, x1, x2, y1, y2, gp ) if gp.instance_of?(Array) then gp_list = gp else gp_list = [gp] end gpn_list = [] gpp_list = [] gp_list.each { |gp_each| # negative gpn = gp_each.copy for k in 0..(gp_each.val.size-1) gpn[k] = [gp_each.val[k],-1e-10].min end # positive gpp = gp_each.copy for k in 0..(gp_each.val.size-1) gpp[k] = [gp_each.val[k],1e-10].max end gpn_list << gpn gpp_list << gpp } DCL.sgfrm svx1_local = svx1 svx2_local = svx1 + ( svx2 - svx1 ) / 2 - ( svx2 - svx1 ) / 2 * 0.02 x1_local = -x2 x2_local = -x1 # DCL.grfig # DCL.sgsvpt(svx1_local,svx2_local,svy1,svy2) DCL.sgswnd(x1_local,x2_local,y1,y2) DCL.grstrn(itr) DCL.grstrf # lidx = DCL.uuqlni() gpn_list.each_with_index { |gpn, i| DCL.uuslni((i+1)*10) DCL.uulin(gpn.val, gpn.coord('Press').val) } DCL.uuslni(lidx) # # DCL.ussttl( gp2outsign.long_name.to_s, '', gp2outsign.coord('Press').long_name, gp2outsign.coord('Press').units.to_s ) # DCL.uzlset( 'labelxt', false ) DCL.uzlset( 'labelxb', false ) DCL.uzlset( 'labelyl', true ) DCL.uzlset( 'labelyr', false ) # DCL.uscset( 'cxside', 'bt' ) # DCL.uscset( 'cyside', 'lr' ) DCL.usdaxs # numeric labels for x flabels=[] clabels=[] log10(x2).to_i.step( log10(x1).to_i, -4 ) do |i| flabels << -10**i clabels << '-10|' + i.to_s + '"' end DCL.uxplbl('b',1,flabels,clabels,4) svx1_local = svx1 + ( svx2 - svx1 ) / 2 + ( svx2 - svx1 ) / 2 * 0.02 svx2_local = svx2 x1_local = x1 x2_local = x2 # DCL.grfig # DCL.sgsvpt(svx1_local,svx2_local,svy1,svy2) DCL.sgswnd(x1_local,x2_local,y1,y2) DCL.grstrn(itr) DCL.grstrf # lidx = DCL.uuqlni() gpp_list.each_with_index { |gpp, i| DCL.uuslni((i+1)*10) DCL.uulin(gpp.val, gpp.coord('Press').val) } DCL.uuslni(lidx) # # DCL.ussttl( '', gp2outsign.units.to_s, gp2outsign.coord('Press').long_name, gp2outsign.coord('Press').units.to_s ) DCL.uzlset( 'labelxt', false ) DCL.uzlset( 'labelxb', false ) DCL.uzlset( 'labelyl', false ) DCL.uzlset( 'labelyr', false ) DCL.usdaxs # numeric labels for x flabels=[] clabels=[] log10(x2).to_i.step( log10(x1).to_i, -4 ) do |i| flabels << 10**i clabels << '10|' + i.to_s + '"' end DCL.uxplbl('b',1,flabels,clabels,4) # # Label DCL.sgsvpt(svx1,svx2,svy1,svy2) DCL.grstrf rsize = DCL.sgqtxs() DCL.sgstxs( rsize*0.5 ) rsizec = DCL.uzpget( 'rsizec1' ) DCL.uzpset( 'rsizec1', rsizec * 0.75 ) DCL.uxsttl('b',"("+gpp_list[0].units.to_s+")",1) DCL.uzpset( 'rsizec1', rsizec ) DCL.sgstxs( rsize ) DCL.uxsttl('b',gpp_list[0].long_name.to_s,0) # DCL.ussttl( '', gp2outsign.units.to_s, gp2outsign.coord('Press').long_name, gp2outsign.coord('Press').units.to_s ) # reset setting DCL.uzlset( 'labelxb', true ) DCL.uzlset( 'labelyl', true ) end
1 つの図に一本の線を描く場合. (gp は単なる GPhys オブジェクト.)
def line_x_log( itr, svx1, svx2, svy1, svy2, x1, x2, y1, y2, gp ) # negative gpn = gp.copy for k in 0..(gp.val.size-1) gpn[k] = [gp.val[k],-1e-10].min end # positive gpp = gp.copy for k in 0..(gp.val.size-1) gpp[k] = [gp.val[k],1e-10].max end DCL.sgfrm svx1_local = svx1 svx2_local = svx1 + ( svx2 - svx1 ) / 2 - ( svx2 - svx1 ) / 2 * 0.02 x1_local = -x2 x2_local = -x1 # DCL.grfig # DCL.sgsvpt(svx1_local,svx2_local,svy1,svy2) DCL.sgswnd(x1_local,x2_local,y1,y2) DCL.grstrn(itr) DCL.grstrf # DCL.uulin(gpn.val, gpn.coord('Press').val) # # DCL.ussttl( gp2outsign.long_name.to_s, '', gp2outsign.coord('Press').long_name, gp2outsign.coord('Press').units.to_s ) # DCL.uzlset( 'labelxt', false ) DCL.uzlset( 'labelxb', false ) DCL.uzlset( 'labelyl', true ) DCL.uzlset( 'labelyr', false ) # DCL.uscset( 'cxside', 'bt' ) # DCL.uscset( 'cyside', 'lr' ) DCL.usdaxs # numeric labels for x flabels=[] clabels=[] log10(x2).to_i.step( log10(x1).to_i, -4 ) do |i| flabels << -10**i clabels << '-10|' + i.to_s + '"' end DCL.uxplbl('b',1,flabels,clabels,4) svx1_local = svx1 + ( svx2 - svx1 ) / 2 + ( svx2 - svx1 ) / 2 * 0.02 svx2_local = svx2 x1_local = x1 x2_local = x2 # DCL.grfig # DCL.sgsvpt(svx1_local,svx2_local,svy1,svy2) DCL.sgswnd(x1_local,x2_local,y1,y2) DCL.grstrn(itr) DCL.grstrf # DCL.uulin(gpp.val, gpp.coord('Press').val) # # DCL.ussttl( '', gp2outsign.units.to_s, gp2outsign.coord('Press').long_name, gp2outsign.coord('Press').units.to_s ) DCL.uzlset( 'labelxt', false ) DCL.uzlset( 'labelxb', false ) DCL.uzlset( 'labelyl', false ) DCL.uzlset( 'labelyr', false ) DCL.usdaxs # numeric labels for x flabels=[] clabels=[] log10(x2).to_i.step( log10(x1).to_i, -4 ) do |i| flabels << 10**i clabels << '10|' + i.to_s + '"' end DCL.uxplbl('b',1,flabels,clabels,4) # # Label DCL.sgsvpt(svx1,svx2,svy1,svy2) DCL.grstrf rsize = DCL.sgqtxs() DCL.sgstxs( rsize*0.5 ) rsizec = DCL.uzpget( 'rsizec1' ) DCL.uzpset( 'rsizec1', rsizec * 0.75 ) DCL.uxsttl('b',"("+gpp.units.to_s+")",1) DCL.uzpset( 'rsizec1', rsizec ) DCL.sgstxs( rsize ) DCL.uxsttl('b',gpp.long_name.to_s,0) # DCL.ussttl( '', gp2outsign.units.to_s, gp2outsign.coord('Press').long_name, gp2outsign.coord('Press').units.to_s ) # reset setting DCL.uzlset( 'labelxb', true ) DCL.uzlset( 'labelyl', true ) end
出力先選択
iws = (ARGV[0] || (puts ' WORKSTATION ID (I) ? ;'; DCL::sgpwsn; gets)).to_i DCL.gropn(iws)
or
print "1: Display, 2: File\n" citr = gets citr = citr.chomp! DCL.gropn(citr.to_i)
内挿
データのファイル出力
outfile = NetCDF.create('data.nc') ... gptmp = gp.copy gptmp.rename( "XXX" ) gptmp.long_name = "long name" gptmp.del_att( 'standard_name' ) GPhys::NetCDF_IO.write( outfile, gptmp ) ... outfile.close
動画作成メモ書き
> convert -rotate 90 -background white -flatten dcl.pdf dcl.tif > convert -crop 776x388+33+65 dcl.tif dcl.jpg > convert -crop 778x389+32+64 dcl.tif dcl.jpg $ convert -rotate 90 dcl.pdf \( +clone -alpha opaque -fill white -colorize 100% \) +swap -geometry +0+0 -compose Over -composite -alpha off dcl.png
参考ページ
注意
convert 使用時に下のようなエラーが出ることがある.
convert-im6.q16: attempt to perform an operation not allowed by the security policy `PDF' @ error/constitute.c/IsCoderAuthorized/408. convert-im6.q16: image sequence is required `+clone' @ error/convert.c/ConvertImageCommand/980.
エラーメッセージで検索すると色々出てくる.
/etc/ImageMagick-6/policy.xml を書き換えると良い.