feature image

2019年4月24日 | ブログ記事

gnuplotで遊ぼう

こんにちは、mds_boyです。
本記事は新歓ブログリレー47日目の記事です。

新入生のみなさん、情報リテラシを履修していますか?
traPに興味がある方の多くは取っているんじゃないかなと思います。

今回紹介するのは、情報リテラシ第二で扱うgnuplotについてです。
(もしかしたらクラスによっては使わないかもしれませんが)

この記事を読めば情報リテラシ楽勝!……とは別にならないと思います。

gnuplotって?

gnuplotは、一般的には実験データをグラフ化したいときに使われるソフトウェアです。

公式サイト

公式サイトにドキュメント(英語, ver5.2)が載っています。
日本語版もありますが若干古い(ver4.6)ので注意です。

インストールはLinux/macOSならパッケージ管理システムから、Windowsなら公式サイトからexeを落とすのが簡単だと思います。

使ってみる

では実際に使ってみます(使い方を知ってる人は飛ばしちゃって大丈夫です)

さて、ターミナル(Winならコマンドプロンプト)を起動して、gnuplotと打ち込むとこんな感じの画面が出ます。

Screenshot-from-2019-04-14-12-31-07

ここでplot sin(x)と打ち込むと、
Screenshot-from-2019-04-14-12-32-20
こんな感じでsin(x)のグラフが表示されます。
簡単ですね!

では次に下のような感じで適当な二次元座標を書いたファイルdata.txtを用意します(名前は何でも良い)

1 1
2 2
3 1
4 3

これが置いてあるディレクトリでplot 'data.txt' with linespointsと打つと

Screenshot-from-2019-04-14-13-51-53

簡単ですね!

こんな感じでグラフを実験データのグラフを描くのに使うのが一般的な用途です。

アニメーション

さて、gnuplotではグラフの描画を時間変化に応じて変更することができます。

do for [i = 0:100 ] {
    pause 0.01
    plot sin(x+i)
}

見ての通りfor文です。
i=0から100まで0.01秒間隔でsin(x+i)を描画します。

適当なファイル名を付けて保存し、load 'ファイル名'として呼び出すと

Peek-2019-04-14-15-27

こんな感じでアニメーションを作ることができます。

ライフゲーム

さてみなさん、ライフゲームって知ってますか?

簡単に言うとマスに生・死があって、一定のルールで生死が変化するのを眺めるものです。
詳しくはwikipediaを読んでください。

ではgnuplotでライフゲームを実装しましょう。

実は、gnuplotは配列を扱うことが出来ます(ver5.2からの新機能です)

配列とforがあればなんとなく実装できそうですね!
というわけでこんな感じです

xsize = 50
ysize = 50

set xrange [0:xsize]
set yrange [0:ysize]

array A[xsize*ysize]
array B[xsize*ysize]
do for [i=1:xsize] {
    do for [j=1:ysize] {
        k = i + (j-1) * xsize
        set object k rect from i,j to i+1,j+1
        A[k] = rand(0) < 0.5
        B[k] = 0
    }
}

do for [n=1:1000] {
    plot 0 lt bgnd
    do for [i=1:xsize] {
        do for [j=1:ysize] {
            k = i + (j-1) * xsize
            if (A[k] == 1) {
                set object k fc rgb "brown"
            } else {
                set object k fc bgnd
            }
        }
    }
    do for [i=1:xsize] {
        do for [j=1:ysize] {
            k = i + (j-1) * xsize
            count = 0
            do for [dx = -1:1] {
                do for [dy = -1:1] {
                    if (dx == 0 && dy == 0) {
                        continue;
                    }
                    nx = (i + dx + xsize - 1) % xsize + 1
                    ny = (j + dy + ysize - 1) % ysize + 1
                    if (A[nx+(ny-1)*xsize] == 1) {
                        count = count + 1
                    }
                }
            }
            if (A[k] == 1) {
                if (count <= 1 || count >= 4) {
                    B[k] = 0
                } else {
                    B[k] = 1
                }
            } else {
                if (count == 3) {
                    B[k] = 1
                } else {
                    B[k] = 0
                }
            }
        }
    }
    do for [i=1:xsize] {
        do for [j=1:ysize] {
            k = i + (j-1) * xsize
            A[k] = B[k]
        }
    }
}

Peek-2019-04-14-18-10

他のプログラミング言語と同じような感じでプログラムを書くことができました。
各マスの生死を0,1で持っておき、毎回色を変えることで表現しています。

ライフゲームはチューリング完全なので、gnuplotもチューリング完全というわけですね。
実際brainfuckのインタプリタを作った人もいます。

おまけ

gnuplotは3次元グラフの描画も行うことができます。
splot x*yとすると
Screenshot-from-2019-04-14-18-32-45

このサイトに立方体の描き方が載っていたので、これを参考にして3Dのライフゲームを描いてみました。
こんな感じです。
元々の機能として回転させることができます。

Peek-2019-04-01-00-39

ついでに立方体に2次元ライフゲームを貼り付けたものも描いてみました(面と面の部分でセルが移動するところが若干バグっています)。

Peek-2019-04-14-18-51

その他参考

http://slpr.sakura.ne.jp/qp/gnuplot-animation/


感想ですが、gnuplotでやる必要あったかな……と思いました。

明日はxecuaくんの記事です。楽しみですね。

mds_boy icon
この記事を書いた人
mds_boy

ゲーム制作や競技プログラミングをしています

この記事をシェア

このエントリーをはてなブックマークに追加
共有

関連する記事

ERC20トークンを用いた宝探しゲーム(真)の提案【アドベントカレンダー2018 10日目】 feature image
2018年11月3日
ERC20トークンを用いた宝探しゲーム(真)の提案【アドベントカレンダー2018 10日目】
Azon icon Azon
2021年5月19日
CPCTF2021を実現させたスコアサーバー
xxpoxx icon xxpoxx
2019年4月22日
アセンブリを読んでみよう【新歓ブログリレー2019 45日目】
eiya icon eiya
2018年12月12日
多重スリーブの世界と,各種進捗報告。
Silviase icon Silviase
2017年11月17日
そばやのワク☆ワク流体シミュレーション~MPS編~
sobaya007 icon sobaya007
2021年4月26日
CPCTF2021 作問者writeup by zassou
zassou icon zassou
記事一覧 タグ一覧 Google アナリティクスについて