Hatena::ブログ(Diary)

sobasobasobaの備忘録

2013-12-31

matplotlib の libping 問題の解決方法

| 21:58

matplotlib を使おうとすると以下のようなエラーが出た。その際に行った解決方法のメモ。

Traceback (most recent call last):
  File "trapezoid.py", line 4, in <module>
    import matplotlib.pyplot as plt
  File "/usr/local/lib/python2.7/site-packages/matplotlib/pyplot.py", line 26, in <module>
    from matplotlib.figure import Figure, figaspect
  File "/usr/local/lib/python2.7/site-packages/matplotlib/figure.py", line 32, in <module>
    from matplotlib.image import FigureImage
  File "/usr/local/lib/python2.7/site-packages/matplotlib/image.py", line 22, in <module>
    import matplotlib._png as _png
ImportError: No module named _png
  1. ここ(http://sourceforge.net/projects/libpng/files/libpng14/) より、libpng-1.4.12.tar.bz2 をダウンロード
  2. 解凍
  3. 出てきたフォルダの下で ./configure
  4. 出てきたフォルダの下で make
  5. 出てきたフォルダの下で make install
  6. matplotlib をインストールしなおす。

2013-12-30

matplotlibで等高線を書く その2

| 16:39

schwefel.png:f:id:sobasobasoba:20131230164102p:image:medium

  1. CS = ax.contour(x, y, z, <等高線の領域数>)
  2. ax.clabel(CS)
    • 各等高線に値を記入
  • clabel関数オプション (一部)
    • fontsize: フォントの大きさ
    • inline: True なら、値の周りの等高線を消す (デフォルトはTrue)
    • colors: 値の色を設定 (何も設定しない場合、等高線と同じ色となる)
#!/usr/bin/env python
#coding:utf-8


from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm
import matplotlib.pyplot as plt
import numpy as np


def schwefel(x, y):
    return 418.9829 * 2 - (x * np.sin(np.sqrt(abs(x))) + \
                           y * np.sin(np.sqrt(abs(y))))


def work():
    N = 100
    MIN_X = -500
    MAX_X =  500

    x = np.linspace(MIN_X, MAX_X, N)
    y = np.linspace(MIN_X, MAX_X, N)
    x, y = np.meshgrid(x, y)
    z = schwefel(x, y)
    
    fig = plt.figure()
    ax = fig.add_subplot(1, 1, 1)

    CS = ax.contour(x, y, z, 5, cmap=cm.coolwarm)
    ax.clabel(CS, fontsize=9, inline=False, colors="black")

    ax.set_title("Schwefel")

    fig.savefig("schwefel.png", bbox_inches="tight")
    

if __name__ == "__main__":
    work()

matplotlibで等高線図を書く

| 16:00

schwefel.png:f:id:sobasobasoba:20131230160144p:image:medium

  • ax.contour(x, y, z, zdir=<x, y, z のいずれか>, offset=<平面のどの位置に描画するか>)
  • contour関数オプション(一部)
    • zdir: どの平面に投射するか(x, y, zのいずれか)
    • offset: 平面のどの位置に描画するか
    • cmap: カラーマップ
#!/usr/bin/env python
#coding:utf-8

from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm
import matplotlib.pyplot as plt
import numpy as np


def schwefel(x, y):
    return 418.9829 * 2 - (x * np.sin(np.sqrt(abs(x))) + \
                           y * np.sin(np.sqrt(abs(y))))


def work():
    N = 100
    MIN_X = -500
    MAX_X =  500

    x = np.linspace(MIN_X, MAX_X, N)
    y = np.linspace(MIN_X, MAX_X, N)
    x, y = np.meshgrid(x, y)
    z = schwefel(x, y)
    
    fig = plt.figure()
    ax = fig.add_subplot(1, 1, 1, projection="3d")

    ax.contour(x, y, z, zdir='z', offset=0, cmap=cm.coolwarm)
    ax.contour(x, y, z, zdir='x', offset=MIN_X, cmap=cm.coolwarm)
    ax.contour(x, y, z, zdir='y', offset=MAX_X, cmap=cm.coolwarm)

    ax.set_title("Schwefel")

    fig.savefig("schwefel.png", bbox_inches="tight")
    

if __name__ == "__main__":
    work()

matplotlibでサーファイスプロットする

| 15:24

schwefel.png: f:id:sobasobasoba:20131230152601p:image:medium:medium

  1. surf = ax.plot_surface(x, y, z)
  2. fig.colorbar(surf)
    • カラーバーの表示
#!/usr/bin/env python
#coding:utf-8


from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm
import matplotlib.pyplot as plt
import numpy as np


def schwefel(x, y):
    return 418.9829 * 2 - (x * np.sin(np.sqrt(abs(x))) + \
                           y * np.sin(np.sqrt(abs(y))))


def work():
    N = 100
    MIN_X = -500
    MAX_X =  500

    x = np.linspace(MIN_X, MAX_X, N)
    y = np.linspace(MIN_X, MAX_X, N)
    x, y = np.meshgrid(x, y)
    z = schwefel(x, y)
    
    fig = plt.figure()
    ax = fig.add_subplot(1, 1, 1, projection="3d")

    surf = ax.plot_surface(x, y, z, cstride=1, rstride=1, cmap=cm.coolwarm, linewidth=0, antialiased=False)
    
    fig.colorbar(surf, shrink=0.5, aspect=10)

    ax.set_title("Schwefel")

    fig.savefig("schwefel.png", bbox_inches="tight")
    

if __name__ == "__main__":
    work()

numpy で3変数の回帰分析

| 10:41

polyfit.png:f:id:sobasobasoba:20131231204443p:image:medium

  • np.polyfit(x, zip(y,z), n)
    • n次式で3変数の回帰分析
  • 3Dデータのプロット
    1. ax = fig.add_subplot(1, 1, 1, projection="3d", azim=<角度>)
    2. ax.plot(x,y,z)
      • azim に値を代入して視点を変える
#!/usr/bin/env python
#coding:utf-8

from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import numpy as np

def read():
    labels = (("car_price", "gas_price", "weight", "co2", "power", "duration"))
    
    ret = []
    ret.append((8895,33,2560,97,113,12))
    ret.append((7402,33,2345,114,90,8))
    ret.append((6319,37,1845,81,63,12))
    ret.append((6635,32,2260,91,92,13))
    ret.append((6599,32,2440,113,103,13))
    ret.append((8672,26,2285,97,82,12))
    ret.append((7399,33,2275,97,90,13))
    ret.append((7254,28,2350,98,74,8))
    ret.append((9599,25,2295,109,90,13))
    ret.append((8748,29,2390,97,102,13))
    ret.append((6488,35,2075,89,78,13))
    ret.append((9995,26,2330,109,100,9))
    ret.append((11545,20,3320,305,170,8))
    ret.append((9745,27,2885,153,100,8))
    ret.append((12164,19,3310,302,225,8))
    ret.append((11470,30,2695,133,110,9))
    ret.append((9410,33,2170,97,108,13))
    ret.append((13945,27,2710,125,140,13))
    ret.append((13249,24,2775,146,140,10))
    ret.append((10565,23,2640,151,110,8 ))
    ret.append((10320,26,2655,133,95,9  ))
    ret.append((10945,25,3065,181,141,12))
    ret.append((9483,24,2750,141,98,9   ))
    ret.append((12145,26,2920,132,125,13))
    ret.append((12459,24,2780,133,110,12))
    ret.append((10989,25,2745,122,102,13))
    ret.append((17879,21,3110,181,142,12))
    ret.append((11650,21,2920,146,138,13))
    ret.append((9995,23,2645,151,110,9  ))
    ret.append((11499,23,2935,135,130,13))
    ret.append((11588,27,2920,122,115,13))
    ret.append((18450,23,2985,141,114,10))
    ret.append((24760,20,3265,163,160,13))
    ret.append((13150,21,2880,151,110,10))
    ret.append((12495,22,2975,153,150,9 ))
    ret.append((16342,22,3450,202,147,10))
    ret.append((15350,22,3145,180,150,9 ))
    ret.append((13195,22,3190,182,140,10))
    ret.append((14980,23,3610,232,140,8 ))
    ret.append((23300,21,3480,180,158,13))
    ret.append((17899,22,3200,180,160,13))
    ret.append((13150,21,2765,151,110,9 ))
    ret.append((21498,23,3480,180,190,10))
    ret.append((16145,23,3325,231,165,10))
    ret.append((14525,18,3855,305,170,8 ))
    ret.append((17257,20,3850,302,150,10))
    ret.append((15395,18,3735,202,150,10))
    ret.append((12267,18,3665,182,145,10))
    ret.append((14944,19,3735,181,150,13))
    
    return labels, np.array(ret)


def work(x, y, z, xLabel, yLabel, zLabel):
    fig = plt.figure()
    ax = fig.add_subplot(2,2,1, projection="3d")
    bx = fig.add_subplot(2,2,2, projection="3d", azim = 30)
    cx = fig.add_subplot(2,2,3, projection="3d", azim = 120)
    dx = fig.add_subplot(2,2,4, projection="3d", azim = 210)
    
    poly = np.polyfit(x, zip(y,z), 1) # 1次式で回帰分析
    yy = np.polyval(poly[:,0], x)   # poly[0][0]: y傾き,  poly[1][0]: y切片
    zz = np.polyval(poly[:,1], x)   # poly[0][1]: z傾き,  poly[1][1]: z切片
    ax.plot(x,yy,zz)
    bx.plot(x,yy,zz)
    cx.plot(x,yy,zz)
    dx.plot(x,yy,zz)

    poly = np.polyfit(x, zip(y,z), 2) # 2次式で回帰分析
    xx = np.arange(x.min(),x.max(),1000)
    yy = np.polyval(poly[:,0],xx)
    zz = np.polyval(poly[:,1],xx)
    ax.plot(xx,yy,zz)
    bx.plot(xx,yy,zz)
    cx.plot(xx,yy,zz)
    dx.plot(xx,yy,zz)

    ax.plot(x, y, z, linestyle="None",marker="o")
    ax.set_xlabel(xLabel)
    ax.set_ylabel(yLabel)
    ax.set_zlabel(zLabel)
    ax.set_title("default (azim = -60)")

    bx.plot(x, y, z, linestyle="None",marker="o")
    bx.set_xlabel(xLabel)
    bx.set_ylabel(yLabel)
    bx.set_zlabel(zLabel)
    bx.set_title("azim = 30")
    
    cx.plot(x, y, z, linestyle="None",marker="o")
    cx.set_xlabel(xLabel)
    cx.set_ylabel(yLabel)
    cx.set_zlabel(zLabel)
    cx.set_title("azim = 120")
    
    dx.plot(x, y, z, linestyle="None",marker="o")
    dx.set_xlabel(xLabel)
    dx.set_ylabel(yLabel)
    dx.set_zlabel(zLabel)
    dx.set_title("azim = 210")

    fig.tight_layout()
    fig.savefig("polyfit.png",bbox_inches="tight")
    

if __name__ == "__main__":
    labels, X = read()

    work(X[:,0], X[:,2], X[:,4], labels[0], labels[2], labels[4])

numpy で2変数の回帰分析

| 10:28

  • np.polyfit(x, y, n)
    • n次式で2変数の回帰分析
  • np.polyval(p, t):
    • pで表される多項式に t を代入し、値を計算して返す
    • p[0]*t**(N-1) + p[1]*t**(N-2) + ... + p[N-2]*t + p[N-1]
#!/usr/bin/env python
#coding: utf-8

import matplotlib.pyplot as plt
import numpy as np


def read():
    labels = (("car_price", "gas_price", "weight", "co2", "power", "duration"))
    
    ret = []
    ret.append((8895,33,2560,97,113,12))
    ret.append((7402,33,2345,114,90,8))
    ret.append((6319,37,1845,81,63,12))
    ret.append((6635,32,2260,91,92,13))
    ret.append((6599,32,2440,113,103,13))
    ret.append((8672,26,2285,97,82,12))
    ret.append((7399,33,2275,97,90,13))
    ret.append((7254,28,2350,98,74,8))
    ret.append((9599,25,2295,109,90,13))
    ret.append((8748,29,2390,97,102,13))
    ret.append((6488,35,2075,89,78,13))
    ret.append((9995,26,2330,109,100,9))
    ret.append((11545,20,3320,305,170,8))
    ret.append((9745,27,2885,153,100,8))
    ret.append((12164,19,3310,302,225,8))
    ret.append((11470,30,2695,133,110,9))
    ret.append((9410,33,2170,97,108,13))
    ret.append((13945,27,2710,125,140,13))
    ret.append((13249,24,2775,146,140,10))
    ret.append((10565,23,2640,151,110,8 ))
    ret.append((10320,26,2655,133,95,9  ))
    ret.append((10945,25,3065,181,141,12))
    ret.append((9483,24,2750,141,98,9   ))
    ret.append((12145,26,2920,132,125,13))
    ret.append((12459,24,2780,133,110,12))
    ret.append((10989,25,2745,122,102,13))
    ret.append((17879,21,3110,181,142,12))
    ret.append((11650,21,2920,146,138,13))
    ret.append((9995,23,2645,151,110,9  ))
    ret.append((11499,23,2935,135,130,13))
    ret.append((11588,27,2920,122,115,13))
    ret.append((18450,23,2985,141,114,10))
    ret.append((24760,20,3265,163,160,13))
    ret.append((13150,21,2880,151,110,10))
    ret.append((12495,22,2975,153,150,9 ))
    ret.append((16342,22,3450,202,147,10))
    ret.append((15350,22,3145,180,150,9 ))
    ret.append((13195,22,3190,182,140,10))
    ret.append((14980,23,3610,232,140,8 ))
    ret.append((23300,21,3480,180,158,13))
    ret.append((17899,22,3200,180,160,13))
    ret.append((13150,21,2765,151,110,9 ))
    ret.append((21498,23,3480,180,190,10))
    ret.append((16145,23,3325,231,165,10))
    ret.append((14525,18,3855,305,170,8 ))
    ret.append((17257,20,3850,302,150,10))
    ret.append((15395,18,3735,202,150,10))
    ret.append((12267,18,3665,182,145,10))
    ret.append((14944,19,3735,181,150,13))
    
    return labels, np.array(ret)


def work(x, y, xLabel, yLabel):
    fig = plt.figure()
    ax = fig.add_subplot(1,1,1)

    poly = np.polyfit(x, y, 1) # 1次式で回帰分析
    yy = np.polyval(poly, x)   # poly[0]: 傾き,  poly[1]: 切片
    ax.plot(x,yy)

    poly = np.polyfit(x, y, 2) # 2次式で回帰分析
    xx = np.arange(x.min(),x.max(),1000)
    yy = np.polyval(poly,xx)   # poly[0] * t^2 + poly[1] * t^1 + poly[0]
    ax.plot(xx,yy)
    
    ax.plot(x,y,linestyle="None",marker="o")
    ax.set_xlabel(xLabel)
    ax.set_ylabel(yLabel)

    fig.savefig("polyfit.png",bbox_inches="tight")


if __name__ == "__main__":
    labels, X = read()
    work(X[:,0], X[:,4], labels[0], labels[4])

2012-12-31

ipython + matplotlib で試しに何かプロットしてみる

| 14:16

  • コンソールで以下を入力し、ipythonを起動。
$ ipython -pylab
  • ipythonで以下を入力
In [1]: plot([1,2,3,4])
In [2]: plot([0,3,2,7])
In [3]: draw()
  • すると、以下のようなウィンドが表示される。

f:id:sobasobasoba:20121231141622p:image:medium

matplotlib のインストール方法

| 13:45

1. NumPy のインストール

$ python setup.py build
$ python setup.py install

2. matplotlibのインストール

$ python setup.py build
$ python setup.py install

(matplotlib を使うためには、 NumPy とセットでインストールすること)

テキスト表示の際、図中の座標値を指定

| 13:38

f:id:sobasobasoba:20121231133834p:image:medium

関数 ax.text(x,y,txt) とすると、描画するデータを基にした(x,y)座標にテキストを表示する。

関数 ax.text(x,y,txt,transform=ax.transAxes) とすると、図の上での(x,y)座標にテキストを表示する。

#!/usr/bin/env python


import matplotlib.pyplot as plt


def plot():
    fig = plt.figure()
    ax = fig.add_subplot(1,1,1)    

    ax.plot([1,2,3,0.5])

    ax.text(0.3,0.1,"ABC",transform=ax.transAxes)
    ax.text(0.4,0.3,"DEF",transform=ax.transAxes)
    ax.text(0.6,0.6,"GHI",transform=ax.transAxes)
    ax.text(0.7,0.8,"JKL",transform=ax.transAxes)
    
    plt.savefig('test.png')


if __name__=="__main__":
    plot()

※参照: http://matplotlib.org/users/transforms_tutorial.html#axes-coordinates

グラフのラベルが重ならないよう自動調整

| 13:32

調整した場合: f:id:sobasobasoba:20121231133405p:image:medium

調整しない場合: f:id:sobasobasoba:20121231133319p:image:medium

fig.tight_layout() とすることで、グラフ同士のラベルが重ならない程度にグラフを小さくする。

#!/usr/bin/env python


import matplotlib.pyplot as plt


def plot():
    fig = plt.figure()

    for r in range(3):
        for c in range(4):
            ax = fig.add_subplot(3,4,r*4+c)

            ax.set_title("Title")
            ax.set_ylabel("Y Label")
            ax.set_xlabel("X Label")
    fig.tight_layout()
    
    plt.savefig('test.png')


if __name__=="__main__":
    plot()

※参照: http://matplotlib.org/users/tight_layout_guide.html

プロット図を縮小して空きを作る(応用)

| 13:19

f:id:sobasobasoba:20121231131903p:image:medium

図の右側に空きを作り、そこに箱髭図の各値(中央値、箱の上端、箱の下端、髭の上端、髭の下端、外れ値)を表示する。

#!/usr/bin/env python


import random
import dateutil.parser as parser
import matplotlib.pyplot as plt
import matplotlib.dates as mdates


def plot():
    val = []
    val.append([random.normalvariate(0,100) for j in range(10000)])
    val.append([random.normalvariate(20,50) for j in range(10000)])    
    
    fig = plt.figure()
    ax = fig.add_subplot(1,1,1)    

    ax.set_ylim([-400,400])
    ax.grid()
    ax.set_xticklabels(["A","B"])

    bp = ax.boxplot(val)

    txt = "A info:\n"
    txt += "Median = %.2f\n"%bp["medians"][0].get_ydata()[0]
    txt += "3rd Quartile = %.2f\n"%bp["boxes"][0].get_ydata()[2]
    txt += "1st Quartile = %.2f\n"%bp["boxes"][0].get_ydata()[0]
    txt += "Upper Whisker = %.2f\n"%bp["whiskers"][1].get_ydata()[1]
    txt += "Lower Whisker = %.2f\n"%bp["whiskers"][0].get_ydata()[1]
    txt += "Highest Flier = %.2f\n"%sorted(bp["fliers"][0].get_ydata())[-1]
    txt += "Lowest Flier = %.2f\n"%sorted(bp["fliers"][1].get_ydata())[0]
    txt += "\n"

    txt += "B info:\n"
    txt += "Median = %.2f\n"%bp["medians"][1].get_ydata()[0]
    txt += "3rd Quartile = %.2f\n"%bp["boxes"][1].get_ydata()[2]
    txt += "1st Quartile = %.2f\n"%bp["boxes"][1].get_ydata()[0]
    txt += "Upper Whisker = %.2f\n"%bp["whiskers"][3].get_ydata()[1]
    txt += "Lower Whisker = %.2f\n"%bp["whiskers"][2].get_ydata()[1]
    txt += "Highest Flier = %.2f\n"%sorted(bp["fliers"][2].get_ydata())[-1]
    txt += "Lowest Flier = %.2f\n"%sorted(bp["fliers"][3].get_ydata())[0]

    ax.text(1.2, 0.1 , txt, fontsize=12, transform=ax.transAxes)
    fig.subplots_adjust(right=0.5)

    plt.savefig('test.png')


if __name__=="__main__":
    plot()

プロット図を縮小して空きを作る

| 13:13

縮小した図: f:id:sobasobasoba:20121231131423p:image:medium

縮小しない図: f:id:sobasobasoba:20121231131431p:image:medium

fig.subplots_adjust(top=0.7) とし、図の上側に空きを作る。

#!/usr/bin/env python


import random
import matplotlib.pyplot as plt


def plot():
    xval = [random.normalvariate( 50,100) for i in range(10000)]
    yval = [random.normalvariate(-50,100) for i in range(10000)]
    
    fig = plt.figure()
    ax = fig.add_subplot(1,1,1)    

    ax.set_xlim([-400,400])
    ax.set_ylim([-400,400])
    ax.grid()

    ax.plot(xval,yval,linestyle="None",marker="+")

    fig.subplots_adjust(top=0.7)

    plt.savefig('test.png')


if __name__=="__main__":
    plot()


subplots_adjust()の仕様:

subplots_adjust(left=None, bottom=None, right=None, top=None, wspace=None, hspace=None)

  • 各値の意味(とデフォルト値):
    • left = 0.125: 図の左端
    • bottom = 0.1: 図の下端
    • right = 0.9: 図の右端
    • top = 0.9: 図の上端
    • wspace = 0.2: subplot間の横幅の空き
    • hspace = 0.2: subplot間の縦幅の空き

デフォルト値は rc ファイルで設定可能。



参照: http://matplotlib.org/api/pyplot_api.html?highlight=subplots_adjust#matplotlib.pyplot.subplots_adjust

shinya_ohtanishinya_ohtani 2015/11/19 20:33 bottomとtopの値が逆のような...

sobasobasobasobasobasoba 2015/12/02 22:36 ご指摘ありがとうございます。修正しました

2012-10-19

箱髭図の値

| 19:59

箱髭図の各値(中央値、箱の上端、箱の下端、髭の上端、髭の下端、外れ値)を取り出す。

下記の例では、図の右側に空きを作るため、空の箱髭図を二つプロットするという姑息な事をしている。

(2012/12/31追記: こちら に、図を縮小して空きを作り、そのスペースに文字列を表示する方法を説明)

f:id:sobasobasoba:20121019195844p:image:medium

import random
import dateutil.parser as parser
import matplotlib.pyplot as plt
import matplotlib.dates as mdates


def plot():
    val = []
    val.append([random.normalvariate(0,100) for j in range(10000)])
    val.append([random.normalvariate(20,50) for j in range(10000)])    
    val.append([])
    val.append([])
    
    fig = plt.figure()
    ax = fig.add_subplot(1,1,1)    

    ax.set_ylim([-400,400])
    ax.grid()
    ax.set_xticklabels(["A","B","",""])

    bp = ax.boxplot(val)

    txt = "A info:\n"
    txt += "Median = %.2f\n"%bp["medians"][0].get_ydata()[0]
    txt += "3rd Quartile = %.2f\n"%bp["boxes"][0].get_ydata()[2]
    txt += "1st Quartile = %.2f\n"%bp["boxes"][0].get_ydata()[0]
    txt += "Upper Whisker = %.2f\n"%bp["whiskers"][1].get_ydata()[1]
    txt += "Lower Whisker = %.2f\n"%bp["whiskers"][0].get_ydata()[1]
    txt += "Highest Flier = %.2f\n"%sorted(bp["fliers"][0].get_ydata())[-1]
    txt += "Lowest Flier = %.2f\n"%sorted(bp["fliers"][1].get_ydata())[0]
    txt += "\n"

    txt += "B info:\n"
    txt += "Median = %.2f\n"%bp["medians"][1].get_ydata()[0]
    txt += "3rd Quartile = %.2f\n"%bp["boxes"][1].get_ydata()[2]
    txt += "1st Quartile = %.2f\n"%bp["boxes"][1].get_ydata()[0]
    txt += "Upper Whisker = %.2f\n"%bp["whiskers"][3].get_ydata()[1]
    txt += "Lower Whisker = %.2f\n"%bp["whiskers"][2].get_ydata()[1]
    txt += "Highest Flier = %.2f\n"%sorted(bp["fliers"][2].get_ydata())[-1]
    txt += "Lowest Flier = %.2f\n"%sorted(bp["fliers"][3].get_ydata())[0]
    
    ax.text(3.0, -250 , txt, fontsize=12)

    plt.savefig('test.png')


if __name__=="__main__":
    plot()

※boxplot関数の返り値に関して、より詳しくは http://www.mail-archive.com/matplotlib-users@lists.sourceforge.net/msg25055.htm を参照。

箱髭図のプロット, その2

| 19:57

横軸を2010年1月〜4月の日付とし、各日[10-50]間の乱数を100個生成し、それを箱髭図としてプロット

横軸のラベルの表示を毎月1日、15日のみにする。

f:id:sobasobasoba:20121019195707p:image:medium

import random
import dateutil.parser as parser
import matplotlib.pyplot as plt
import matplotlib.dates as mdates

def plot():
    x = []
    x.extend([parser.parse("2010/01/%02d"%dd) for dd in range(1,31+1)])
    x.extend([parser.parse("2010/02/%02d"%dd) for dd in range(1,28+1)])
    x.extend([parser.parse("2010/03/%02d"%dd) for dd in range(1,31+1)])
    x.extend([parser.parse("2010/04/%02d"%dd) for dd in range(1,30+1)])

    val = []
    for i in range(len(x)):
        val.append([random.randint(10,50) for j in range(100)])
    

    fig = plt.figure()
    ax = fig.add_subplot(1,1,1)    

    ax.set_ylim([0,100])
    ax.grid()
    ax.boxplot(val,positions=mdates.date2num(x))

    days = mdates.DayLocator(bymonthday=[1,15])
    daysFmt = mdates.DateFormatter("%b/%d")
    ax.xaxis.set_major_locator(days)
    ax.xaxis.set_major_formatter(daysFmt)
    
    plt.savefig('test.png')


if __name__=="__main__":
    plot()

箱髭図のプロット

| 19:56

ラベルA: [10-50]間の乱数を1000個生成し、それを箱髭図としてプロット

ラベルB: 平均5, 標準偏差30 の正規分布に従う乱数を1000個生成し、それを箱髭図としてプロット

ラベルC: 平均10, 標準偏差20 の正規分布に従う乱数を1000個生成し、それを箱髭図としてプロット


f:id:sobasobasoba:20121019195552p:image:medium

import random
import dateutil.parser as parser
import matplotlib.pyplot as plt
import matplotlib.dates as mdates

def plot():
    val = []
    val.append([random.randint(10,50) for j in range(1000)])
    val.append([random.normalvariate(5,30) for j in range(1000)])
    val.append([random.normalvariate(10,20) for j in range(1000)])

    fig = plt.figure()
    ax = fig.add_subplot(1,1,1)

    ax.set_ylim([-100,100])
    ax.grid()
    ax.set_xticklabels(["A","B","C"])
    ax.boxplot(val)

    plt.savefig('test.png')


if __name__=="__main__":
    plot()

※boxplot関数に関して、より詳しくは http://matplotlib.org/api/pyplot_api.html?highlight=boxplot#matplotlib.pyplot.boxplot を参照。

時系列データのプロット, その2

| 19:52

横軸を2010年1月〜4月の日付とし、各日[10-50]間の乱数をプロット

横軸のラベルの表示を毎月1日、15日のみにする。

f:id:sobasobasoba:20121019195236p:image:medium

import random
import dateutil.parser as parser
import matplotlib.pyplot as plt
import matplotlib.dates as mdates

def plot():
    x = []
    x.extend([parser.parse("2010/01/%02d"%dd) for dd in range(1,31+1)])
    x.extend([parser.parse("2010/02/%02d"%dd) for dd in range(1,28+1)])
    x.extend([parser.parse("2010/03/%02d"%dd) for dd in range(1,31+1)])
    x.extend([parser.parse("2010/04/%02d"%dd) for dd in range(1,30+1)])

    val = []
    for i in range(len(x)):
        val.append(random.randint(10,50))
    

    fig = plt.figure()
    ax = fig.add_subplot(1,1,1)    

    ax.set_ylim([0,100])
    ax.grid()
    ax.plot(x,val)

    days = mdates.DayLocator(bymonthday=[1,15])
    daysFmt = mdates.DateFormatter("%b/%d")
    ax.xaxis.set_major_locator(days)
    ax.xaxis.set_major_formatter(daysFmt)
    
    plt.savefig('test.png')


if __name__=="__main__":
    plot()

DayLocator(bymonthday=[1,15]) とすることで、毎月1日,15日のみラベルを表示させることができる。

※より詳しくは、 http://matplotlib.org/api/dates_api.html#matplotlib.dates.DayLocator を参照

時系列データのプロット

| 19:46

[3-7]の乱数値、[4-9]の乱数値を生成して、30分刻みの時系列データとしてプロット

f:id:sobasobasoba:20121019194640p:image:medium

#!/usr/bin/env python

import random
import dateutil.parser as parser
import matplotlib.pyplot as plt
import matplotlib.dates as mdates

def plot():
    x = ["00:00", "00:30", "01:00", "01:30", "02:00", "02:30",
         "03:00", "03:30", "04:00", "04:30", "05:00", "05:30",
         "06:00", "06:30", "07:00", "07:30", "08:00", "08:30",
         "09:00", "09:30", "10:00", "10:30", "11:00", "11:30",
         "12:00", "12:30", "13:00", "13:30", "14:00", "14:30",
         "15:00", "15:30", "16:00", "16:30", "17:00", "17:30",
         "18:00", "18:30", "19:00", "19:30", "20:00", "20:30",
         "21:00", "21:30", "22:00", "22:30", "23:00", "23:30"]

    xval = [parser.parse(xv) for xv in x]
    yval1 = [random.randint(3,7) for i in range(48)]
    yval2 = [random.randint(4,9) for i in range(48)]
    
    fig = plt.figure()

    ax = fig.add_subplot(1,1,1)
    ax.plot(xval,yval1,marker='o',linestyle="-",label="y1")
    ax.plot(xval,yval2,marker='x',linestyle="--",label="y2")
    ax.set_ylim(0,10)
    ax.set_xlabel("Time")
    ax.set_ylabel("Y Value")
    ax.legend(loc="upper right")
    ax.grid()

    days = mdates.AutoDateLocator()
    daysFmt = mdates.DateFormatter("%H:%M")
    ax.xaxis.set_major_locator(days)
    ax.xaxis.set_major_formatter(daysFmt)

    plt.savefig("test.png")

    plt.close()


if __name__=="__main__":
    plot()


plot()の仕様(一部):

plot(x, y, marker='o', linestyle="-", label="xxx")

  • x: x要素のデータ(datetime型)
  • y: y要素のデータ
  • linestyle: 点同士をどのような線で結ぶか
  • legend: 凡例名

※より詳しくは、http://matplotlib.org/api/axes_api.html#matplotlib.axes.Axes.plot を参照



Locator について: 時系列データの目盛の間隔を設定する

  • set_major_locator() の引数として、以下のいずれかのインスタンスを代入する
    • matplotlib.mdates.AutoDateLocator(): 自動的に間隔を決定
    • matplotlib.mdates.MonthLocator(): 月間隔
    • matplotlib.mdates.DayLocator(): 日間隔
    • matplotlib.mdates.HourLocator(): 時間隔
    • matplotlib.mdates.MinuteLocator(): 分間隔
    • etc.

※上記のサンプルコードで、AutoDateLocator() でなく、 HourLocator() を設定すると、目盛間隔が1時間ごとになる。

f:id:sobasobasoba:20121019194553p:image:medium

※より詳しくは、http://matplotlib.org/api/dates_api.html#date-tickers を参照



Formatter について: 日付のラベルの表示形式を設定する

  • set_major_formatter() の引数に、以下のいずれかのインスタンスを代入する
    • matplotlib.mdates.AutoDateFormatter(): 自動的に表示形式を設定
    • matplotlib.mdates.DateFormatter(): 引数にstrを代入して、表示形式を指定
      • matplotlib.mdates.DateFormatter("%H:%M"): 表示形式は "時:分" となる
      • matplotlib.mdates.DateFormatter("%m/%d %H:%M"): 表示形式は "月/日 時:分" となる
    • etc.

 ※より詳しくは、 http://matplotlib.org/api/dates_api.html#date-formatters を参照

散布図のプロット

| 19:35

平均 100, 標準偏差 50 の正規分布に従う乱数を10000個生成(x要素のデータとする)。

平均 -200, 標準偏差 100 の正規分布に従う乱数を10000個生成(y要素のデータとする)。

各xy要素を散布図としてプロットする。

f:id:sobasobasoba:20121019193512p:image:medium

#!/usr/bin/env python


import random
import matplotlib.pyplot as plt


def plot():
    xmu = 100
    xsigma = 50
    XMIN = -100
    XMAX =  300

    ymu = -200
    ysigma = 100
    YMIN = -400
    YMAX =  0
    
    N = 10000

    x = [random.normalvariate(xmu,xsigma) for i in range(N)]
    y = [random.normalvariate(ymu,ysigma) for i in range(N)]
    
    fig = plt.figure()

    ax = fig.add_subplot(1,1,1)
    ax.plot(x,y,marker='+',linestyle="None")
    ax.set_xlim(XMIN,XMAX)
    ax.set_ylim(YMIN,YMAX)
    ax.set_xlabel("X data")
    ax.set_ylabel("Y data")
    ax.grid()
    
    plt.savefig("test.png")

    plt.close()


if __name__=="__main__":
    plot()

plot()の仕様(一部):

plot(x, y, color='green', linestyle='None', marker='+', markersize=12)

  • x: x要素のデータ
  • y: y要素のデータ
  • color: どの色で点をプロットするか
  • linestyle: 点同士をどのような線で結ぶか(散布図をプロットする場は'None'とする)
  • marker: どの節点でプロットするか
  • markersize: 節点の大きさ

※より詳しくは、http://matplotlib.org/api/axes_api.html#matplotlib.axes.Axes.plot を参照

ヒストグラムのプロット

| 19:31

平均 50, 標準偏差 250 の正規分布に従う乱数を10000個生成し、

そのヒストグラムを作成する。


f:id:sobasobasoba:20121019193220p:image:medium

#!/usr/bin/env python


import random
import matplotlib.pyplot as plt


def plot():
    mu = 50
    sigma = 250
    MAX = 1000
    MIN = -1000
    N = 10000

    data = [random.normalvariate(mu,sigma) for i in range(N)]

    fig = plt.figure()

    ax = fig.add_subplot(1,1,1)
    ax.hist(data, bins=100, range=(MIN,MAX))
    ax.set_ylabel("frequency")
    ax.grid()
    
    plt.savefig("test.png")

    plt.close()


if __name__=="__main__":
    plot()

hist()の仕様(一部):

hist(x, bins=100, range=(-1000,1000), normed=False, cumulative=False, histtype="bar")

  • x: ヒストグラムにする対象のデータ
  • bins: 縦棒の本数(デフォルトは10)
  • range: 表示する横軸の幅(デフォルトは(xの最小値,xの最大値))
  • normed: 度数をデータ数で正規化するかどうか(デフォルトはFalse)
  • cumulative: 累積ヒストグラムとして表示するか(デフォルトはFalse)
  • histtype: ヒストグラムのタイプ。"bar" の他, "step", "stepfilled"等がある (デフォルトは"bar")

hist()の返り値: (pdf, bins, patches)

  • pdf: 各縦棒の度数が、リストで格納される
  • bins: 各縦棒の値が、リストで格納される
  • patches: 各縦棒の座標値が格納される。

      (histtype="bar"ならmatplotlib.patches.Rectangle、histtype="step"なら、matplotlib.patches.Polygon)

※より詳しくは、http://matplotlib.org/api/axes_api.html#matplotlib.axes.Axes.hist を参照