化石もできる! Matplotlib.Pyplot
東成都でもプログラミング教育が推進されている今日この頃。認可校レギュラーヒーローの浅桐くんと武居くん、2人がPythonでグラフを描くことに挑戦するようですよ!
1話 ある日の合宿施設にて
武居「グラフはパソコンで描いていいっつってたけどWordじゃ描けねぇしExcelは使いにくいんだよな……」
浅桐「おう化石、Microsoft方眼紙で何やってんだァ? $${x^2+(y-\sqrt{|x|})^2=1}$$ ……ハン、このグラフを描きてェのね」
武居「こっち来んな」
浅桐「そーいう面倒なのはExcelよりpltのがいいぜ、化石に使えるかは知らんがな」
武居「あ???????? いいぜやってやろうじゃねぇかよ!」
浅桐「ソースコードだけ読ませろっていうせっかち野郎はすぐ上の目次から9話まで飛べ」
2話 環境構築(pip, NumPy, Matplotlib)
浅桐「Python自体は前チョロっと教えてやったな」※存在しない前回
武居「ぶいえすこーどとかいうよく分かんねぇアプリ入れやがった時だな」
浅桐「VSCode舐めてんじゃねェぞ……端末、あー、ターミナル開け」
武居「ターミナル? そんなアプリねぇし入れるなよ」
浅桐「後から入れるモンじゃねェよ!? Winじゃコマンドプロンプトっつーのか……もう頼城みてーにMac使え」
武居「MacBook高ぇよ。おら開いてやったぞ」
浅桐「pipは前入れたから`pip list`って打ってみろ」
武居「チッ……うわ、何か出た」
C¥Users¥kazutaka>pip list
Package Version
---------- -------
future 0.18.2
pip 21.2.4
setuptools 58.0.4
six 1.15.0
wheel 0.37.0
浅桐「`pip install numpy`と`pip install matplotlib`やってみろ」
武居「何だその呪文……おいまた何か変なの入れさせやがっただろ! ふざけんな!」
浅桐「NumPyはてめェの数学ライフを大いに助けてくれるありがたいライブラリ様! Matplotlibはグラフ描くやつだ」
武居「ナンパイに比べてマットプロットリブの扱いが雑」
3話 配列の用意
浅桐「コンピュータでグラフ描く時は大抵、
描きたい関数に対応する配列を作る
グラフの描画設定を整える
の2ステップ要るな。まず配列作るぞ、VSCode開け」
武居「Excelでxとyの数値めっちゃ用意するやつか、パイソンでも描き方変わんねーのな」
浅桐「コンピュータにアナログな関数の概念は厳しいからな、SymPyは手計算と似たようなコトもできるらしいがNumPyのが有名だろ」
武居「パイ多いな」
浅桐「お前もプリンパイだろ、仲良くやんな」
武居「正義!! あの野郎!!」
import numpy as np
from matplotlib import pyplot as plt
x = np.linspace(-1, 1, 101) # -1 <= x <= 1
武居「いきなり打ち込むな! 何だこれ?」
浅桐「1行目はNumPyの、2行目はMatplotlib.pyplotのimportだ。さっきインストールしたヤツをコード内でこう書くと使えるようになる」
武居「入れただけじゃダメなのかよ」
浅桐「名前空間の明示は大切だからな。`np`と`plt`は略称だ。そんで`np.linspace`でxの配列を作る」
武居「Excelで数字入れるのと同じ……なのか?」
浅桐「本質的にはな。明らかに $${-1 \leq x \leq 1}$$ だからとりあえず101点用意したぞ、一応点が多いほど滑らかなグラフになる」
武居「yは場合分けが要るのか、面倒くせぇ」
浅桐「陰関数を描く方法もある筈だが最初は陽のがいいわな」
武居「陰関数って敬がこの前騒いでたな」
$$
y = \sqrt{|x|} + \sqrt{1 - x^2}\quad (y \geq 0) \\
y = \sqrt{|x|} - \sqrt{1 - x^2}\quad (y < 0) \\
$$
武居「xは絶対値と二乗しか出てこないな、左右対称なのか?」
浅桐「お、化石にしてはいい目の付け所」
武居「一言余計だ」
浅桐「後は配列作ってやりゃいい」
yupper = np.sqrt(np.abs(x)) + np.sqrt(1 - x ** 2)
ylower = np.sqrt(np.abs(x)) - np.sqrt(1 - x ** 2)
武居「sqrtはsquare root、absはabsoluteか。英語知ってれば意外と読みやすいな」
4話 グラフの描画設定
浅桐「次にグラフだ、まずは`plt.subplots()`で`fig`と`ax`を作れ」
武居「何だそれ」
浅桐「Excelでいうグラフエリアとプロットエリアだ、タイトルや軸もグラフの上に要るだろ」
武居「axって斧じゃねぇか? 軸はaxisだろ」
浅桐「慣例だ、クソだと思うならお前が覇権を取れ」
武居「どうでもいいわ」
fig, ax = plt.subplots(tight_layout=True)
武居「タイトレイアウト? って何だ」
浅桐「グラフが見切れないようにする引数だ、まぁお守りみてーなモンよ」
武居「へぇ、ちゃんと意味があんだな」
浅桐「無意味なコードなんざ無ェよ、コードも言葉だからな」
武居「知るか」
浅桐「チッ……作った`ax`にyどもをプロットしてくぞ、2通りあるから2回やることになるな」
ax.plot(x, yupper, 'k-')
ax.plot(x, ylower, 'k-')
武居「xとyは分かるがその次のは何だ?」
浅桐「グラフの色と形を決める文字列だ。`k`は黒、`-`は直線。マーカーも付けられるしかなり自由自在に設定できるが、化石向けに一番シンプルなのにしてやった」
武居「シンプルはいいが言葉は毎度余計だ」
浅桐「後はタイトル付けたり軸ラベル付けたり。実のところExcelとやってるコトは変わらねェ、ボタン押すか文字書くかってだけだ」
武居「全然思えねぇ」
fig.suptitle(r'$x^2+(y-\sqrt{|x|})^2=1$')
ax.set_xlabel(r'$x$')
ax.set_ylabel(r'$y$')
武居「文字はクォーテーションで囲まなきゃダメなんじゃなかったのか? rはみ出てるぞ」
浅桐「これはraw文字列だ。特殊な文字の働きを無効にする」
武居「ナマか」
浅桐「タイトルや軸に数式を入れるならとりあえずこれ付けて式を`$`で囲め。TeX使えるのはいいよな」
浅桐「グラフを保存して、最後に表示。順番間違えると白紙が保存されっから気をつけろ」
fig.savefig('kasekiplot.png')
plt.show()
武居「何だその名前!」
浅桐「さっきのコマンドプロンプトで実行してみろ。まずファイルのあるデスクトップに移動して、プログラムを実行」
C¥Users¥kazutaka>cd desktop
C¥Users¥kazutaka¥Desktop>python plot.py
武居「うお、出たっ」
5話 フォントの変更
浅桐「提出はできるがちっとダセェな……フォントいじるか」
plt.rcParams['font.family'] = 'Times New Roman'
plt.rcParams['mathtext.fontset'] = 'cm'
浅桐「とりあえずTimes New Roman使っとくぜ、数式はCambria Mathでいいかァ?」
武居「カンブリア? どんなフォントだよ」
浅桐「Wordの数式で使われてるヤツ」
武居「そんな名前だったんだな」
浅桐「よし、再実行してみろ」
6話 アスペクト比の変更
武居「お、文字が数式っぽくなってるけどなんか潰れてる?」
浅桐「アスペクト比変えた方がいいな」
武居「アスペクト?」
浅桐「画像の縦横比だ」
ax.set_aspect('equal')
武居「1対1になるようにしたのか」
7話 解像度の変更
武居「yの最大値が1.5くらいある分少し縦長になったな……なんか画像荒くね?」
浅桐「マジだ、dpiもいじるか。これ印刷すんのか?」
武居「いや、PDFにしてサイトで出す」
浅桐「じゃあそんなに要らねェな……200で足りるか」
武居「dpiがでかすぎると何か困るのか?」
浅桐「綺麗な画像になるがサイズが重くなる。この辺は久森のが詳しいかもな」
fig.savefig('kasekiplot.png', dpi=200)
8話 垂直線と水平線の表示
武居「x軸やy軸は付けらんねぇのか?」
浅桐「化石が思いつくことはもう実装されてるぜ、当然にな」
ax.axvline(0, linestyle=':', color='k')
ax.axhline(0, linestyle=':', color='k')
浅桐「vは垂直、hは水平線。NumPyもよくこの名付け方してるな」
武居「kはさっきと同じで黒か。ラインスタイルはコロン……点線か?」
浅桐「分かってきたじゃねェの」
9話 完成!
武居「いいんじゃね? Wordに貼って出そ」
浅桐「化石の思わぬハイテク化に驚愕喝采間違いナシだな」
武居「本当うるせえ……けどまぁサンキュ」
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
code in this article. by M. Asagiri
"""
import numpy as np
from matplotlib import pyplot as plt
x = np.linspace(-1, 1, 101) # -1 <= x <= 1
yupper = np.sqrt(np.abs(x)) + np.sqrt(1 - x ** 2)
ylower = np.sqrt(np.abs(x)) - np.sqrt(1 - x ** 2)
plt.rcParams['font.family'] = 'Times New Roman'
plt.rcParams['mathtext.fontset'] = 'cm'
fig, ax = plt.subplots(tight_layout=True)
ax.set_aspect('equal')
ax.plot(x, yupper, 'k-')
ax.plot(x, ylower, 'k-')
fig.suptitle(r'$x^2+(y-\sqrt{|x|})^2=1$')
ax.set_xlabel(r'$x$')
ax.set_ylabel(r'$y$')
ax.axvline(0, linestyle=':', color='k') # y axis
ax.axhline(0, linestyle=':', color='k') # x axis
fig.savefig('kasekiplot.png', dpi=200)
plt.show()
10話 後日の白星第一学園にて
武居「結局印刷されたが……悪くねぇな」
御鷹「一孝、それ宿題? グラフすごく綺麗」
武居「色々あって生まれた。今度教えてやるよ」
御鷹「ほんと? 楽しみにしてる」
武居「そうだ、正義どこにいるか知らね? とっちめる」
御鷹「正義さんならもう会議室じゃないかな。どうしたの?」
武居「分かった行ってくる」
御鷹「一孝ー!?」
11話 あとがきというか雑感
武居一孝誕生日おめでとう!!!!!!!
浅桐さんは実験メインのようですが解析にも手を出していそうだしFortran使ってそう。コードの属人性や思想についてもう少し掘り下げたかったです。
存在しない前回や志藤がmarkdownやる回も書きたいものです。
浅桐「`range`は関数じゃねェ!!」とか書きたい(`type`使って確認すると分かりますがクラスとして定義されています)。
mAsagiri:~$ python
Python 3.11.4 (default, Jun 7 2023, 16:26:54) [Clang 14.0.0 (clang-1400.0.29.102)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> print(type(range))
<class 'type'>
>>> print(type(type))
<class 'type'>
浅桐さんは武居のPCに直接PythonとVSCode入れてます(武居「勝手に入れるな!」)がGoogleアカウントあれば Colaboratoryがおすすめです。
御鷹はプログラミング向いてそう。自然言語より文法がきっちりしてるので。御鷹と武居と浅桐さんの組み合わせはいつかのバケツ通信クロストークを思い起こさせますね。