未分類

matplotlibについて

2022年8月31日

https://matplotlib.org/stable/index.html

matplotlib

Matplotlibはwikipediaによると「プログラミング言語Pythonおよびその科学計算用ライブラリNumPyのためのグラフ描画ライブラリである。オブジェクト指向のAPIを提供しており、様々な種類のグラフを描画する能力を持つ。」
というように、数値系データをさまざまなグラフで表示させる機能が揃ったライブラリです。
そしてオブジェクト指向のAPIという記載がある通り、
matplotlibは以下のような階層構造になっています。
 

matplotlib
∟pyplotクラス
∟xlimメソッド
∟ylimメソッド
∟shoeメソッド
∟imageクラス
∟legendクラス
・・・
 

上記のように、matplotlibライブラリの中にはさまざまなグラフを表示するグラフがあります。
つまりpyplotという散布図などを作成して表示するクラス、データの凡例を作成して表示させるクラス、、、などなど。
そして、その中にメソッドと呼ばれるものがあります。
 

イメージとしてはメソッドを呼ぶとその中にplotオブジェクトのプロパティに値が付与され、
その値を用いてshowなどでグラフを表示するようなイメージになります。
 


matplotlibでは、以下のような階層構造になっている。
matplotlibは

import matplotlib.pyplot と呼ぶことで、まずそのmatplotlibライブラリのpyplotクラスを読み込むということになります。
そしてas plotとすることで、plotオブジェクトを生成します。
plotオブジェクトが生成されたので、それによりさまざまなメソッドを呼んで作成していく形になります。
 

実際に三角関数のグラフを表示させてみます。

import numpy as np
import matplotlib.pyplot as pyplot

x = np.arange(-5, 5, 0.1) #-5から5まで0.1区切りで配列を作る
y = np.sin(x) #配列xの値に関してそれぞれsin(x)を求めてy軸の配列を生成
# ランダムデータを出したい場合は、
# np.random.binaryなどのように記載する。np.ramdom

plt.plot(x,y) # この場合のplot関数の第一引数xは、x軸に対応し、第二引数のyがy軸にあたります。
plt.show()

xに範囲を指定してそれまでの連続値を出した上で、
yでsin(x)とすることで、
各xに対してyの値ができ、(x,y)ができますので、その値を結んでいくことでsin(x)を表示するような感じになります。
 

そしてplotオブジェクトに対してメソッドを実行していくことでplotオブジェクトに情報が付与されます。そして最後にshowすることでそのplotオブジェクトを作図します。

plotオブジェクトの中身を確認する

実際に上記のコードにprint(plt)を記載して、
pltオブジェクトの中身を確認してみます。

import numpy as np
import matplotlib.pyplot as plt

x = np.arange(-5, 5, 0.1) #-5から5まで0.1区切りで配列を作る
y = np.sin(x) # xデータに対してsin(x)処理をする

plt.plot(x,y)
print(plt)
plt.show()

そうすると、

という表示がされました。
中身がわかりませんね。
 

これは。。。を意味していますが、今見たいのはその具体的な中身です。
そのため、以下のプログラムを追加します。

import pprint
pprint.pprint(vars(plt))

これでpltを表示してみると、以下のようにいろいろ表示されます。

ここでプロパティ、に入れてみます。
そうしてまたpltしてみると、更新されているのが確認できます。

このようにplotにはさまざまな情報が格納されていき、それによってshowメソッドを実行すると、その情報をもとにグラフを表示するということになります。
 

rcParams

rcParamsでフォントなどのデフォルト設定をします。
線を実線ではなく点線にしたり。設定できる。

import matplotlib.pyplot as plt
print(plt.rcParams)

以下のようにすることでまとめて更新できるが、
pythonはdict型があるので、
plt.rcParams["lines.linestyle"] = "dotted"
で更新でも問題ありません。

import matplotlib.pyplot as plt
import numpy as np

x= np.arange(-4,4,0.01)
y = np.tanh(x)

config = {
    "lines.linestyle":"dotted",
    "lines.linewidth":10,
    "xtick.labelbottom":False,
    "xtick.labeltop":True,
    "ytick.labelleft":False,
    "ytick.labelright":True
}

plt.rcParams.update(config)
plt.plot(x,y)
plt.show()

https://tech-market.org/matplotlib-rcparams/
 

複数のグラフを1つの図に表示

普通にplt.plotにそのまま入れることで表示できる。

import numpy as np
import matplotlib.pyplot as plt
import pprint

x = np.arange(0, 1, 0.01) 
y = x

z = np.random.rand(100)
a = np.random.rand(100)

plt.plot(x,y) # この場合のplot関数の第一引数xは、x軸に対応し、第二引数のyがy軸にあたります。
plt.scatter(z,a)  # scatterは散布図 (plotはパスなので線になる)
plt.show()

pltという作図オブジェクトにplotという線のグラフ、scatterという散布図を呼んでるので、最後にshowすることでそれぞれが1つの中に作図される。

1つのplt
つまり作図するのはpltオブジェクト
これをshowすると1つのグラフ表が作成され、その中に複数のグラフが表示されました。
1つのグラフ表を作成するので、xlimも1つしか設定できません。titleやylimも。
plt.xlim
plt.ylim
plt.title

FigureとAxseの関係

プロットの仕方として、Figureとaxesの2つが重要になります。
これら2つは以下で作成できます。
figure, axes = plt.subplots()

そしてfigureとaxesは何を意味しているのでしょうか?
普通にplt.showをすると、1つの図しか出ません。
しかし複数表示させたい場合もあります。
その時に関わってきます。
figureはその描写全体のことを指すので基本的に1つになります。
そしてその中に作成する図はaxesと言います。
なので、このaxesを複数作成するというイメージになります。

import numpy as np
import matplotlib.pyplot as plt

#figure()でグラフを表示する領域をつくり,figというオブジェクトにする.
fig = plt.figure()

#add_subplot()でグラフを描画する領域を追加する.引数は行,列,場所
ax1 = fig.add_subplot(2, 2, 1)
ax2 = fig.add_subplot(2, 2, 2)
ax3 = fig.add_subplot(2, 2, 3)
ax4 = fig.add_subplot(2, 2, 4)
どこに配置するかを指定する。
2,2,1はfigure全体を2*2にした上で、その左上を基準として1番目ということ。

pltは最大のオブジェクトで、このオブジェクトで操作をします。
pltオブジェクトによって、まず全体の描写であるfigureを生成します。
fig = plt.figure()

そして、そのfigureの中にさまざまな図を表示するので、
ax1 = fig.add_subplot()で図を作成していきます。
これが図のオブジェクトになるので、これに対して
色々散布図のscatter、パスを表示するplotなど
ax1.scatter()
ax1.plot()

そもそも別にfigureじゃあ2つ作って何か意味あるの?

ax4 = fig.add_subplot(1,1,1)
ax1 = fig.add_subplot(2,2,1)
ax2 = fig.add_subplot(2,2,2)
ax3 = fig.add_subplot(2,2,3)
とすると、
まず、ax4は1,1,1なので、figure全体をまず1*1にした上で、1番目なので結局figure全体になります。(もし1,1,2とすると、これはあり得ないのでエラーになる。)

ax1は2,2,1なので、
figure全体を2*2にした上で、左上を基点として1番目なので以下の黄色の箇所に配置される。

ax1 = fig.add_subplot(2,2,1)
ax2 = fig.add_subplot(2,2,2)
ax3 = fig.add_subplot(2,2,3)
ax4 = fig.add_subplot(1,1,1)
とするとどうなるか。

定義した順に上書きされていくので、上の同じfigureに描画する中で、一番最後のax4がまさに1,1,1のfigure全体に描画する感じになっているので、
ax1,2,3を描画した後に、全体がax4によって上書きされてしまっている状態になります。

そして1,1,2とすると当然ながら描写できないので、以下のようにエラーになります。

 

以下のようにしてみます。
ax1 = fig.add_subplot(3,3,1)
ax2 = fig.add_subplot(3,3,5)
ax3 = fig.add_subplot(3,3,9)

そして、axesは図なので、
結局ax1.hist(ヒストグラム)や、ax1.scatter(散布図)、ax1.plot(パス図なので確率密度関数とか)など作図ができる

figureの大きさを変える

axesの大きさを変更したいのであれば、figureの大きさを変更することになります。
axesはfigureをいくつかに分けたうちの1つの領域に図示するため、そもそものfigureサイズを変更する必要があります。
変更は以下のように設定します。
fig = plt.figure(figsize=(21,14))
figsizeの1個目が横軸(x軸)、第2引数が縦軸(y軸)になる。
 

それかrcParamsにも、以下があるのでそれで変えることも可能。
plt.rcParams["figure.figsize"] = (21,14)
好きなサイズで。
 

%matplotlib

https://www.datacamp.com/tutorial/matplotlib-tutorial-python

-未分類

© 2022 Yosshi Blog Powered by AFFINGER5