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
2023年4月27日
Vulkanのデバイスドライバを自作してみた
kegra icon kegra
2024年4月14日
Spotifyのクライアントを自作しよう
d_etteiu8383 icon d_etteiu8383
2021年12月8日
C++ with JUCEでステレオパンを作ってみた【AdC2021 26日目】
liquid1224 icon liquid1224
2019年4月22日
アセンブリを読んでみよう【新歓ブログリレー2019 45日目】
eiya icon eiya
記事一覧 タグ一覧 Google アナリティクスについて 特定商取引法に基づく表記