Hatena::ブログ(Diary)

sobasobasobaの備忘録

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")

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 を参照