0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【necoplot】長文matplotlibを少し簡潔にできるライブラリ

Posted at

記事の背景

necoplotというライブラリを作ったのでその紹介記事です。
matplotlibをちょっとだけ簡潔に書くことができます。

Githubにも公開しています。 -> Github necoplot

この記事の想定読者

  • Pythonでmatplotlibを使う
  • matplotlibの作図をもう少し簡潔にやりたい
  • 人がつくったライブラリの話に興味がある(※)

※ 筆者は独学の非エンジニアです。
「そういう人でもこういうのつくれるんだ〜」
くらいに思っていただければ幸いです。

結論

  • ものぐさな筆者が自分のためにつくりました
  • 引数をわりと適当に入れてもわりと大丈夫なようにつくりました
  • matplotlibの引数やメソッドはだいたいそのまま使えるはずです

ライブラリの特徴とメリット

  • wiht文を使って一部のコード記述を簡略化してます
  • 図の設定を引数を介して行うことで、コードの行数を削減してます
  • デフォルト値を設定でき、引数入力の手間を省けるようにしています

インストール

pip install necoplotでインストールできます。
(作りたてなので今後挙動の変更がいろいろ生じるかもしれませんm(_ _)m)

使用例

下準備

import necoplot as necoとしておきます。1

import necoplot as neco
import numpy as np

xx = np.linspace(-5,5,20)
yy = xx*xx

以降xの2乗のグラフを題材にしていきます。

最もシンプルな例

with neco.plot() as ax:という形式で使います。2
まずは引数を何も入れないプレーンな状態から。

# Basic
with neco.plot() as ax:
    ax.plot(xx, yy)

example01_basic

簡素な図ですが、2行で作図できました。
処理としては、with文に入る時にfigureを作って、出る時にplt.show()しています。

figureの設定

いわゆるfig = plt.figure()の部分です。
necoplotではneco.plot()の引数に設定する値を投入できます。

画像の縦横比や色などを変更してみます。

# Config figiure
with neco.plot(figsize=(4,4), dpi=80, facecolor='silver') as ax:
    ax.plot(xx, yy)

example02_config_figure

地味な図ではありますが、こちらも2行で作図できました。

axの設定1: figureの設定と一緒に

figureの次はax(図)の設定をします。
axもfigureと同じようにneco.plot()の引数として設定することができます。

本来は別々に扱う引数ですが、ちょっとした設定で行追加するのが面倒だったので、
figureと同じところから引数を代入できるようにしています。

今度はfigureの設定と同時にaxの設定もします。
xの範囲を(-5〜0)の範囲に限定した図をつくります。

# Config ax by plot() 
with neco.plot(figsize=(6,4), xlim=(-5,0)) as ax:
    ax.plot(xx, yy) 

example03_config_by_plot

裏側では投入された引数を選り分けて、figure用とax用に割り振ったりしています。

余談: figureとax

figureとaxの違いは、matplotlibの少しややこしいところです。

筆者の雑な理解でいうと、たとえるならfigureは画板です。
その上に具体的な図(ここではax)が載るイメージです。

よって基本的にfigureは1つですが、axは複数使うことができます。
実際にこのあと複数のaxを使うケースも見ていきます。

axの設定2: 関数を使って設定する

先ほどはfigureと同じneco.plot()からaxの設定を行いましたが、
今度はneco.config_ax()を使ってaxの設定を行います。

neco.plot()だと少し煩雑になる場合には、こちらのほうがスッキリします。
この場合は、neco.config_ax()の結果をneco.plot()に渡してあげます。

ここではxの範囲の指定に加えて、タイトルをつけて、xのスケールを対数スケールに変更しています。
(図の設定に深い意味はありません)

# Config ax by using config_ax()
ax0 = neco.config_ax(xlim=(1,5), title='title', xscale='log')

with neco.plot(ax0, figsize=(6,4)) as ax:
    ax.plot(xx, yy)

example04_config_ax

実は、ここでのax0は関数なので、with文の中でそのまま使うことはできません。

neco.config_ax()は関数をつくる関数ということになります。
with文に入る前はax(図)を貼るfigure(画板)が準備できないので、こういう仕様になりました。

axの設定3: axに直接設定を加える

with neco.plot() as ax:のaxは、matplotlibのAxesクラスです。

よって、matplotlibのaxでやっていたことはだいたい再現できるはずです。
(例: ax.plot(), ax.bar(), ax.set_xlim()…etc)

この場合もaxを使って追加の設定をいろいろしています。

# Config ax directry
with neco.plot() as ax:
    ax.plot(xx, yy, label='x squared')
    ax.legend()
    ax.hlines(y=25, xmin=-5, xmax=5)

example05_config_directry

なんとなくドラえもんのポケットみたいですね。

図の保存

図の保存にはneco.save()を使います。
showオプションをFalseにすると、図の描写はせずに画像の保存だけ実行してくれます。

# Save figure
with neco.plot() as ax:
    ax.plot(xx, yy)
    neco.save('sample.png', show=False)

show=Falseなので画像も省略します。

複数のax(図)を1つのfigure(画板)に描写する

複数の図を描写する際にはneco.mplot()を使います。
multiplotの略でmplotです。3

複数の図を描写するので、画板のどこに配置するかの「番地」を指定する必要があります。

最初の引数の121122がそれにあたります。
この3桁で(行数,列数,順番)が表現されています。

121は1行2列の1番目、122は1行2列の2番目を指定しています。

# Plot multiple with mplot()
ax0 = neco.config_ax(121, xlim=(-5, 0),title='Left side')
ax1 = neco.config_ax(122, xlim=(0, 5), title='Right side', yticks=[])

with neco.mplot([ax0, ax1]) as p:
    p.axes[0].plot(xx, yy)
    p.axes[1].plot(xx, yy)

exmaple08

見た目をスッキリさせるために、2つの図の間のy軸の目盛りを省略してみました。
この3桁の記法で最大9つの図を1枚の画板に収録できます。

よく使う引数をデフォルト値に設定する

いくつか図を作っていると、複数の図で共通して使う引数が出てくることがあります。
毎回同じ引数を書くのがめんどうなので、デフォルト値の引数を設定できるようにしました。

あくまでデフォルト値を設定しているだけなので、
個別に他の値を代入すればそちらが優先して反映されます。

以下の図は直接neco.plot()に何も引数を与えなくても、
neco.config_user_parameters()で設定したタイトルが反映されている例です。

# Config default values
neco.config_user_parameters(title='New default title!')

with neco.plot() as ax: # 引数を設定していない
    ax.plot(xx, yy)

example07_config_params

タイトルを設定していなくても、新しい画像にタイトルがつきました。
デフォルト値の再設定にはデコレータなどを使っています。

設定をリセットする

設定したデフォルト値をすべて取り消したい場合は、neco.reset()を使います。

# Reset config
neco.reset()

ちなみに、猫リセットといえば…4

もう少し手の込んだ例

最後に、matplotlib公式を参考にもう少し手の込んだ作図をしてみます。5

グルーブごとの棒グラフ

データの準備

import numpy as np

title = 'Scores by group and gender'
labels = ['G1', 'G2', 'G3', 'G4', 'G5']
ylabel = 'Scores'

x = np.arange(len(labels))
men_means = [20, 34, 30, 35, 27]
women_means = [25, 32, 34, 20, 25]
width = 0.35

作図

ax0 = neco.config_ax(title=title, ylabel=ylabel, xticks=x, xticklabels=labels)

with neco.plot(ax0) as ax:
    ax.bar(x - width/2, men_means, width, label='Men')
    ax.bar(x + width/2, women_means, width, label='Women')
    ax.legend()

example09_grouped_bars

散布図と棒グラフ

データの準備

np.random.seed(0)

x0, y0 = np.random.normal(size=(2, 200))

x1 = np.arange(5)
y11, y12 = np.random.randint(1, 25, size=(2, 5))
width = 0.25

作図

ax0 = neco.config_ax(121)
ax1 = neco.config_ax(122, xticks=range(5), xticklabels=['a', 'b', 'c', 'd', 'e'])

with neco.mplot([ax0, ax1]) as p:
    p.axes[0].plot(x0, y0, 'o')
    p.axes[1].bar(x1, y11, width)
    p.axes[1].bar(x1+width, y12, width)

example10_scatter_and_bars

ずっと放物線のグラフばっかり紹介していましたが、
それ以外のグラフもきちんと描けることが確認できました。

雑感

  • エンジニアじゃなくても、その気があればライブラリをつくって公開できることがわかった
  • 自分でライブラリを作るとPythonの色んな仕様を調べる機会になるので、よい勉強になった

まとめ

  • necoplotを使って(比較的)簡潔に作図できるようになった!
  • ライブラリを自分でつくると色々勉強になる!
  1. nekoではなくnecoなのは、nekoplotが先に存在していて、名前が被ったためです。

  2. コンテキストマネージャーを使う方法はあきとしのスクラップノートさんの以下の記事を参考にさせていただきました。
    [python] context manger を使ってmatplotlibの図を大量生産する
    あきとしさんの作成されたライブラリcontextpltは以下のリンクをご参照ください。
    https://toshiakiasakura.github.io/contextplt/index.html

  3. 短いほうが書きやすいしかわいいので、可読性を少し犠牲にしました。

  4. お気づきの方もいるかもですが、「ずっと真夜中でいいのに。」の『猫リセット』をモチーフ(?)にしています。
    筆者はずとまよのファンなので、この関数を実装することをモチベーションに開発がんばりました。
    ずっと真夜中でいいのに。『猫リセット』MV (ZUTOMAYO - Neko Reset)

  5. https://matplotlib.org/3.5.0/gallery

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?