IT pass HikiWiki - [Exp2023]NetCDF データの可視化 ruby の初歩 Diff
- Added parts are displayed like this.
- Deleted parts are displayed
like this.
((<"スケジュール表・各回資料 (08/09)"|[Exp2023]スケジュール表・各回資料#08-2F09>))
{{toc}}
GPhys は ((<Ruby|URL:https://www.ruby-lang.org/ja/>)) というスクリプト言語の枠組みの上で用いる可視化ライブラリです.
Ruby では他のコンピュータ言語と同様に繰り返しや条件分岐と言った処理が可能で, それらを知っていることは GPhys を使った可視化の際にも有益です.
ここでは, ruby での (画面への)出力, 繰り返し, 条件分岐の方法について簡単に紹介します.
#----------------------------------------------------------------------------
= 出力, 繰り返し, 条件分岐
出力, 繰り返し, 条件分岐を使ったスクリプトの例を下に示します.
((<basics.rb|URL:/exp/fy2023/230809/practice_gphys/basics.rb>))
01 #!/usr/bin/ruby
02
03 # print: 画面 (標準出力) への出力
04 # ただし, print で改行するためには改行記号 ("\n") が必要.
05 print "こんにちは."
06 print "こんばんは.\n"
07
08 # p: 画面 (標準出力) への出力
09 # 値の出力に加えて変数の型の情報 (文字列や数値型など) も出力
10 # 例えば, 文字列を出力するとダブルクォーテーション "" で囲まれて出 力される
11 # 数値を出力すると囲まれない
12 # さらに改行も自動的に出力される
13 p "こんにちは."
14 p "こんばんは."
15 p 10
16
17 # 1 から 10 までの偶数の和の計算
18
19 # 合計を入れる変数 num の初期化
20 # C 言語とは異なり変数の宣言は不要
21 num = 0
22
23 # for: 繰り返し
24 # 構文
25 # for <変数> in <開始値>..<終了値>
26 # ... 処理 ...
27 # end
28 for i in 1..10
29
30 # 繰り返し数の表示
31 print "LOOP: ", i, "\n"
32
33 # 和の計算
34 # 偶数のみ足す
35 # "%" は剰余 (余り) を計算する演算子
36 # if: 条件分岐
37 # 構文
38 # if <条件式> then
39 # ... 処理 ...
40 # (elsif <条件式> then)
41 # ... 処理 ...
42 # (else)
43 # ... 処理 ...
44 # end
45 if i % 2 == 0 then
46 num = num + 1
47 end
48
49 end
50
51 # 和の表示
52 print "合計: ", num, "\n"
このスクリプトの実行結果は下のようになるでしょう.
$ ruby basics.rb
こんにちは.こんばんは. <- print の出力 (最初の print には改行がないので一行になっている)
"こんにちは." <- p の出力
"こんばんは." <- p の出力
10
LOOP: 1 <- for の中の print の出力
LOOP: 2 <- for の中の print の出力
LOOP: 3 <- for の中の print の出力
LOOP: 4 <- for の中の print の出力
LOOP: 5 <- for の中の print の出力
LOOP: 6 <- for の中の print の出力
LOOP: 7 <- for の中の print の出力
LOOP: 8 <- for の中の print の出力
LOOP: 9 <- for の中の print の出力
LOOP: 10 <- for の中の print の出力
合計: 30 <- print の出力
上のスクリプトを簡単に解説します.
* 画面への出力
* 5-6 行目
* print は非常に素直に与えられた変数を出力します.
陽に指定しない限り改行が表示されないことに注意しましょう.
改行するためには改行文字 "\n" を与えなければなりません.
* 13-15 行目
* p は与えられた変数の値に加えてその方の情報も出力します.
改行文字を与えなくても自動的に改行されます.
* 上の例では, 文字の出力時にはダブルクォーテーションで囲われることで文字型であることが表現されており, 数値 (整数) の出力時には囲われないことで数値 (文字型でない) ことが表現されています.
* 繰り返し
* 28-49 行目
* for は繰り返しの方法の一つです. 繰り返しの開始と終了の値を指定することで動作します.
* 条件分岐
* 45-47 行目
* if 文は基本的な条件分岐の方法です.
条件判定のための演算子としては下のようなものを使うことができます.
* A == B : A と B が等しい
* A != B : A と B が等しくない
* A > B : A が B より大きい
* A >= B : A が B 以上
* A < B : A が B より小さい
* A <= B : A が B 以下
* また, 複数の条件を課す時には以下を使うことができます.
* (条件1) && (条件2) : (条件1) かつ (条件2)
* (条件1) || (条件2) : (条件1) または (条件2)
また, 21 行目のように変数を使う場合には, 変数の宣言は必要ありません.
(C 言語などでは変数の宣言が必須です.)
#----------------------------------------------------------------------------
= GPhys オブジェクト情報の確認
GPhys オブジェクトは単なる数値ではなく, 複数次元の数値の配列とメタデータを含むオブジェクトです.
これまで見てきたように, 描画する際にはこのオブジェクトから目的とする領域を切り出したり, 次元を指定したりして加工します.
しかし, 様々に加工していくと, ある GPhys オブジェクトの内容が分からなくなってしまうこともあるでしょう.
GPhys では, p メソッドを使うことで GPhys オブジェクトの内容を確認することができます.
下に, その例を示します.
((<basics_2.rb|URL:/exp/fy2023/230809/practice_gphys/basics_2.rb>))
01 #!/usr/bin/ruby
02 # 使用するライブラリの読み込み. (以下 2 行は「決まり文句」.)
03 require "numru/ggraph"
04 include NumRu
05
06 # NetCDF ファイル"air.2019.nc" "air.2023.nc" から変数 "air" を読み, GPhys オブジェクト gp に
07 # 格納
08 gp = GPhys::IO.open"air.2019.nc", "air.2023.nc", "air"
09
10 # gp の内容を表示
11 p gp
12
13 # 区切りの表示
14 print "-----\n"
15
16 # gp の内容を表示 その 2
17 p gp.cut('lon'=>0)
このスクリプトを実行すると下のように表示されます.
$ ruby basics_2.rb
<NumRu::GPhys grid=<4D grid <axis pos=<'lon' in'air.2019.nc' 'air.2023.nc' sfloat[144]>>
<axis pos=<'lat' in'air.2019.nc' 'air.2023.nc' sfloat[73]>>
<axis pos=<'level' in'air.2019.nc' 'air.2023.nc' sfloat[17]>>
<axis pos=<'time' in'air.2019.nc' 'air.2023.nc' float[365]>>>
data=<'air' in'air.2019.nc' 'air.2023.nc' sfloat[144, 73, 17, 365]>>
-----
<NumRu::GPhys grid=<3D grid <axis pos=<'lat' shape=[73] subset of a NumRu::VArrayNetCDF>>
<axis pos=<'level' shape=[17] subset of a NumRu::VArrayNetCDF>>
<axis pos=<'time' shape=[365] subset of a NumRu::VArrayNetCDF>>>
data=<'air' shape=[73, 17, 365] subset of a NumRu::VArrayNetCDF>>
GPhys オブジェクトが, はじめは lon, lat, level, time の 4 つの次元と, それらを次元・軸とする 4 次元データ air を持っていることがわかります. しかし, cut メソッドで経度を指定した後では, 次元は lat, level, time の 3 つしかなく, 変数 air も 3 次元データとなっていることがわかります.
#----------------------------------------------------------------------------
= 対話的処理環境
Ruby には対話的に処理を実行する環境として irb (Interactive Ruby) が用意されています.
「対話的に実行する」とは, コマンドを入力するとその場で応答があって, それに基づいて次の処理を入力し, その場で応答があって, ... といった, 言ってみれば Linux のシェルでのコマンド実行と同じ環境です.
逆に, ここまでに説明してきたような, ファイルにスクリプトを書いておいてスクリプトを実行するやり方は「非対話的」ということになります.
対話的な処理環境では, 入力したコマンド・処理に対してすぐに応答があるために処理の問題点を探しやすく, コマンドや処理を試す際に大変有益です.
#また, pry では, スクリプトファイルに「仕掛け」をしておくことで, スクリプトの実行途中から対話的処理を行うことができるため, スクリプトのデバッグ (バグ取り, 間違い修正) のために大変便利です.
#
#なお, pry はインストールされていないかもしれませんので, 必要に応じて以下のようにしてインストールしてください.
#
# $ sudo apt-get install ruby-pry-byebug
irb は下のように使うことができます. irb を起動すると下のようなプロンプトが表示されます.
$ irb
irb(main):001:0>
ここで, Ruby のコマンドを実行できます.
例えば下のように四則演算や Ruby の構文の確認ができます.
$ irb
irb(main):001:0> 1.38e-23 * 6.02e23 <- 掛け算の結果
=> 8.3076 <- 掛け算の結果
irb(main):002:0> k = 1.38e-23 <- 変数への代入
=> 1.38e-23
irb(main):003:0> Na = 6.02e23 <- 変数への代入
=> 6.02e+23
irb(main):004:0> k * Na <- 変数同士の掛け算
=> 8.3076 <- 掛け算の結果
irb(main):005:0> a = 2
=> 2
irb(main):006:0> if a > 1 then <- if 文のお試し
irb(main):007:1* print "greater than 1" <- if 文のお試し
irb(main):008:1> else <- if 文のお試し
irb(main):009:1> print "less than or equal to 1" <- if 文のお試し
irb(main):010:1> end <- if 文のお試し
greater than 1=> nil <- if 文の結果
また, GPhys を用いた処理も, これまでの説明でファイルに保存していた内容を入力することで同じ処理ができ, 動作を確認することができます.
上の例は非常に簡単なものですが, 例えば計算機代わりのちょっとした計算もできますし, Ruby の練習に大変役に立ちます.
{{toc}}
GPhys は ((<Ruby|URL:https://www.ruby-lang.org/ja/>)) というスクリプト言語の枠組みの上で用いる可視化ライブラリです.
Ruby では他のコンピュータ言語と同様に繰り返しや条件分岐と言った処理が可能で, それらを知っていることは GPhys を使った可視化の際にも有益です.
ここでは, ruby での (画面への)出力, 繰り返し, 条件分岐の方法について簡単に紹介します.
#----------------------------------------------------------------------------
= 出力, 繰り返し, 条件分岐
出力, 繰り返し, 条件分岐を使ったスクリプトの例を下に示します.
((<basics.rb|URL:/exp/fy2023/230809/practice_gphys/basics.rb>))
01 #!/usr/bin/ruby
02
03 # print: 画面 (標準出力) への出力
04 # ただし, print で改行するためには改行記号 ("\n") が必要.
05 print "こんにちは."
06 print "こんばんは.\n"
07
08 # p: 画面 (標準出力) への出力
09 # 値の出力に加えて変数の型の情報 (文字列や数値型など) も出力
10 # 例えば, 文字列を出力するとダブルクォーテーション "" で囲まれて出 力される
11 # 数値を出力すると囲まれない
12 # さらに改行も自動的に出力される
13 p "こんにちは."
14 p "こんばんは."
15 p 10
16
17 # 1 から 10 までの偶数の和の計算
18
19 # 合計を入れる変数 num の初期化
20 # C 言語とは異なり変数の宣言は不要
21 num = 0
22
23 # for: 繰り返し
24 # 構文
25 # for <変数> in <開始値>..<終了値>
26 # ... 処理 ...
27 # end
28 for i in 1..10
29
30 # 繰り返し数の表示
31 print "LOOP: ", i, "\n"
32
33 # 和の計算
34 # 偶数のみ足す
35 # "%" は剰余 (余り) を計算する演算子
36 # if: 条件分岐
37 # 構文
38 # if <条件式> then
39 # ... 処理 ...
40 # (elsif <条件式> then)
41 # ... 処理 ...
42 # (else)
43 # ... 処理 ...
44 # end
45 if i % 2 == 0 then
46 num = num + 1
47 end
48
49 end
50
51 # 和の表示
52 print "合計: ", num, "\n"
このスクリプトの実行結果は下のようになるでしょう.
$ ruby basics.rb
こんにちは.こんばんは. <- print の出力 (最初の print には改行がないので一行になっている)
"こんにちは." <- p の出力
"こんばんは." <- p の出力
10
LOOP: 1 <- for の中の print の出力
LOOP: 2 <- for の中の print の出力
LOOP: 3 <- for の中の print の出力
LOOP: 4 <- for の中の print の出力
LOOP: 5 <- for の中の print の出力
LOOP: 6 <- for の中の print の出力
LOOP: 7 <- for の中の print の出力
LOOP: 8 <- for の中の print の出力
LOOP: 9 <- for の中の print の出力
LOOP: 10 <- for の中の print の出力
合計: 30 <- print の出力
上のスクリプトを簡単に解説します.
* 画面への出力
* 5-6 行目
* print は非常に素直に与えられた変数を出力します.
陽に指定しない限り改行が表示されないことに注意しましょう.
改行するためには改行文字 "\n" を与えなければなりません.
* 13-15 行目
* p は与えられた変数の値に加えてその方の情報も出力します.
改行文字を与えなくても自動的に改行されます.
* 上の例では, 文字の出力時にはダブルクォーテーションで囲われることで文字型であることが表現されており, 数値 (整数) の出力時には囲われないことで数値 (文字型でない) ことが表現されています.
* 繰り返し
* 28-49 行目
* for は繰り返しの方法の一つです. 繰り返しの開始と終了の値を指定することで動作します.
* 条件分岐
* 45-47 行目
* if 文は基本的な条件分岐の方法です.
条件判定のための演算子としては下のようなものを使うことができます.
* A == B : A と B が等しい
* A != B : A と B が等しくない
* A > B : A が B より大きい
* A >= B : A が B 以上
* A < B : A が B より小さい
* A <= B : A が B 以下
* また, 複数の条件を課す時には以下を使うことができます.
* (条件1) && (条件2) : (条件1) かつ (条件2)
* (条件1) || (条件2) : (条件1) または (条件2)
また, 21 行目のように変数を使う場合には, 変数の宣言は必要ありません.
(C 言語などでは変数の宣言が必須です.)
#----------------------------------------------------------------------------
= GPhys オブジェクト情報の確認
GPhys オブジェクトは単なる数値ではなく, 複数次元の数値の配列とメタデータを含むオブジェクトです.
これまで見てきたように, 描画する際にはこのオブジェクトから目的とする領域を切り出したり, 次元を指定したりして加工します.
しかし, 様々に加工していくと, ある GPhys オブジェクトの内容が分からなくなってしまうこともあるでしょう.
GPhys では, p メソッドを使うことで GPhys オブジェクトの内容を確認することができます.
下に, その例を示します.
((<basics_2.rb|URL:/exp/fy2023/230809/practice_gphys/basics_2.rb>))
01 #!/usr/bin/ruby
02 # 使用するライブラリの読み込み. (以下 2 行は「決まり文句」.)
03 require "numru/ggraph"
04 include NumRu
05
06 # NetCDF ファイル
07 # 格納
08 gp = GPhys::IO.open
09
10 # gp の内容を表示
11 p gp
12
13 # 区切りの表示
14 print "-----\n"
15
16 # gp の内容を表示 その 2
17 p gp.cut('lon'=>0)
このスクリプトを実行すると下のように表示されます.
$ ruby basics_2.rb
<NumRu::GPhys grid=<4D grid <axis pos=<'lon' in
<axis pos=<'lat' in
<axis pos=<'level' in
<axis pos=<'time' in
data=<'air' in
-----
<NumRu::GPhys grid=<3D grid <axis pos=<'lat' shape=[73] subset of a NumRu::VArrayNetCDF>>
<axis pos=<'level' shape=[17] subset of a NumRu::VArrayNetCDF>>
<axis pos=<'time' shape=[365] subset of a NumRu::VArrayNetCDF>>>
data=<'air' shape=[73, 17, 365] subset of a NumRu::VArrayNetCDF>>
GPhys オブジェクトが, はじめは lon, lat, level, time の 4 つの次元と, それらを次元・軸とする 4 次元データ air を持っていることがわかります. しかし, cut メソッドで経度を指定した後では, 次元は lat, level, time の 3 つしかなく, 変数 air も 3 次元データとなっていることがわかります.
#----------------------------------------------------------------------------
= 対話的処理環境
Ruby には対話的に処理を実行する環境として irb (Interactive Ruby) が用意されています.
「対話的に実行する」とは, コマンドを入力するとその場で応答があって, それに基づいて次の処理を入力し, その場で応答があって, ... といった, 言ってみれば Linux のシェルでのコマンド実行と同じ環境です.
逆に, ここまでに説明してきたような, ファイルにスクリプトを書いておいてスクリプトを実行するやり方は「非対話的」ということになります.
対話的な処理環境では, 入力したコマンド・処理に対してすぐに応答があるために処理の問題点を探しやすく, コマンドや処理を試す際に大変有益です.
#また, pry では, スクリプトファイルに「仕掛け」をしておくことで, スクリプトの実行途中から対話的処理を行うことができるため, スクリプトのデバッグ (バグ取り, 間違い修正) のために大変便利です.
#
#なお, pry はインストールされていないかもしれませんので, 必要に応じて以下のようにしてインストールしてください.
#
# $ sudo apt-get install ruby-pry-byebug
irb は下のように使うことができます. irb を起動すると下のようなプロンプトが表示されます.
$ irb
irb(main):001:0>
ここで, Ruby のコマンドを実行できます.
例えば下のように四則演算や Ruby の構文の確認ができます.
$ irb
irb(main):001:0> 1.38e-23 * 6.02e23 <- 掛け算の結果
=> 8.3076 <- 掛け算の結果
irb(main):002:0> k = 1.38e-23 <- 変数への代入
=> 1.38e-23
irb(main):003:0> Na = 6.02e23 <- 変数への代入
=> 6.02e+23
irb(main):004:0> k * Na <- 変数同士の掛け算
=> 8.3076 <- 掛け算の結果
irb(main):005:0> a = 2
=> 2
irb(main):006:0> if a > 1 then <- if 文のお試し
irb(main):007:1* print "greater than 1" <- if 文のお試し
irb(main):008:1> else <- if 文のお試し
irb(main):009:1> print "less than or equal to 1" <- if 文のお試し
irb(main):010:1> end <- if 文のお試し
greater than 1=> nil <- if 文の結果
また, GPhys を用いた処理も, これまでの説明でファイルに保存していた内容を入力することで同じ処理ができ, 動作を確認することができます.
上の例は非常に簡単なものですが, 例えば計算機代わりのちょっとした計算もできますし, Ruby の練習に大変役に立ちます.