授業-ソフトウェア工学 > 2019年度 > 第10回


授業-2019年度-ソフトウェア工学-第10回

*

(公開)


  • 01~15の数字をクリックすると当該回のページに移動します
    • 数字の後の星印(*)はスタッフページへのリンクです
*

*


*


概要

  • 今日は,個別に要望があって,前回の試験後に実施した,追試の問題の公開と,それをベースにした課題をやっていただきます.
  • 時間があれば,Pythonでの数値計算に重要なNumpyと,可視化に重要なmatplotlibについて,いろいろやってみましょう.
    • Numpyとmatplotlibは,いずれも,海外の大学では非常によく使われていたMatlabというプログラミング言語と似た機能を提供しています.
      • Numpyで重要な要素としては,配列(matrix ないし array)が扱えることがあります.
        • リストで代用するのではなく,本当のn次元配列(numpy.ndarray)です.
        • そのため,同じ型の要素しか含めることはできません.が,計算は速いです.
          • デフォールトは,float64(64bit浮動小数点です).しばらくは,これを使いましょう.

* Matplotlibの例題

正規分布のヒストグラム

import numpy as np
import matplotlib.pyplot as plt

data = np.random.randn( 10000 )              # 標準正規分布(平均0, 標準偏差1)
plt.hist( data, bins=100 )                   # ヒストグラム(100分割)
plt.show()

import numpy as np
import matplotlib.pyplot as plt

data = np.random.normal( 50, 10, 10000 )     # 正規分布(平均50, 標準偏差10)
plt.hist( data, bins=100 )                   # ヒストグラム(100分割)
plt.show()

カイ二乗分布のヒストグラム

import numpy as np
import matplotlib.pyplot as plt

data = list()
for i in range( 10 ):
    # 標準正規分布を二乗する
    data.append( np.random.normal( 0, 1, 10000 ) ** 2 )

# 正規分布の二乗をn個足し合わせると,自由度n-1のカイ二乗分布
for j in range( 2, 10 ):
    x = data[0]
    for i in range( 1, j ):
        x += data[i]
    plt.hist( x, 100 )
    plt.show()

import numpy as np
import matplotlib.pyplot as plt

for j in range( 2, 10 ):
    x = np.random.chisquare( j, 10000 )
    plt.hist( x, 100 )
    plt.show()

相関係数と散布図

import numpy as np
import matplotlib.pyplot as plt

# データを生成する.
x = np.random.rand( 100 )
y = np.random.rand( 100 )

print( "相関係数", np.corrcoef(x, y)[0][1] )
plt.scatter( x,y )

plt.show()

サインとコサイン

import numpy as np
import matplotlib.pyplot as plt

x_min = -np.pi
x_max = np.pi
x = np.arange( x_min, x_max, 0.1 )

y_sin = np.sin( x )
y_cos = np.cos( x )

plt.plot( x, y_sin )
plt.plot( x, y_cos )

plt.title( "sin(x) & cos(x)")

plt.xlim( x_min, x_max )
plt.ylim( -1.5, 1.5 )

plt.tight_layout()

plt.show()
  • サブプロット

import numpy as np
import matplotlib.pyplot as plt

x_min = -np.pi
x_max = np.pi
x = np.arange( x_min, x_max, 0.1 )

y_sin = np.sin( x )
y_cos = np.cos( x )

# サブプロット[1] 2行1列の1つ目
plt.subplot( 2, 1, 1 )
plt.plot( x, y_sin )
plt.title( "sin(x)" )
plt.xlim( x_min, x_max )
plt.ylim( -1.5, 1.5 )

# サブプロット[2] 2行1列の2つ目
plt.subplot( 2, 1, 2 )
plt.plot( x, y_cos )

plt.title( "cos(x)" )
plt.xlim( x_min, x_max )
plt.ylim( -1.5, 1.5 )

plt.tight_layout()

plt.show()

レーダーチャート

# 参考: Matplotlibでレーダーチャートを描く(16行)
#        https://qiita.com/1007/items/80406e098a4212571b2e
# 参考: How to Draw Radar Chart with Python in a Simple Way
#        https://typewind.github.io/2017/09/29/radar-chart/

import matplotlib.pyplot as plt
import numpy as np

labels = [ 'HP', 'Attack', 'Defense', 'Sp. Atk', 'Sp. Def', 'Speed' ]
values = [100, 200, 150, 180, 175, 250]
angles = np.linspace(0, 2 * np.pi, len(labels) + 1, endpoint=True)

values = np.concatenate( (values, [values[0]]) )

fig = plt.figure()
ax = fig.add_subplot( 111, polar=True )

ax.plot(angles, values, 'o-')
ax.fill(angles, values, alpha=0.25)
ax.set_thetagrids(angles[:-1] * 180 / np.pi, labels)
ax.set_rlim(0 ,250)

fig.show()

顔型グラフ

# ライセンス不明につき,今後,掲載を中止することもあります.
# https://gist.github.com/aflaxman/4043086
# https://healthyalgorithms.com/2012/11/12/dataviz-in-python-chernoff-faces-with-matplotlib/

import matplotlib
import matplotlib.pyplot as plt

from numpy.random import rand
from numpy import pi, arctan

def cface(ax, x1,x2,x3,x4,x5,x6,x7,x8,x9,x10,x11,x12,x13,x14,x15,x16,x17,x18):
    # x1 = height  of upper face
    # x2 = overlap of lower face
    # x3 = half of vertical size of face
    # x4 = width of upper face
    # x5 = width of lower face
    # x6 = length of nose
    # x7 = vertical position of mouth
    # x8 = curvature of mouth
    # x9 = width of mouth
    # x10 = vertical position of eyes
    # x11 = separation of eyes
    # x12 = slant of eyes
    # x13 = eccentricity of eyes
    # x14 = size of eyes
    # x15 = position of pupils
    # x16 = vertical position of eyebrows
    # x17 = slant of eyebrows
    # x18 = size of eyebrows
    
    # transform some values so that input between 0,1 yields variety of output
    x3 = 1.9*(x3-.5)
    x4 = (x4+.25)
    x5 = (x5+.2)
    x6 = .3*(x6+.01)
    x8 = 5*(x8+.001)
    x11 /= 5
    x12 = 2*(x12-.5)
    x13 += .05
    x14 += .1
    x15 = .5*(x15-.5)
    x16 = .25*x16
    x17 = .5*(x17-.5)
    x18 = .5*(x18+.1)

    # top of face, in box with l=-x4, r=x4, t=x1, b=x3
    e = matplotlib.patches.Ellipse( (0,(x1+x3)/2), 2*x4, (x1-x3), fc='white', edgecolor='black', linewidth=2)
    # e.set_clip_box(ax.bbox)
    # e.set_facecolor([0,0,0])
    ax.add_artist(e)

    # bottom of face, in box with l=-x5, r=x5, b=-x1, t=x2+x3
    e = matplotlib.patches.Ellipse( (0,(-x1+x2+x3)/2), 2*x5, (x1+x2+x3), fc='white', edgecolor='black', linewidth=2)
    ax.add_artist(e)

    # cover overlaps
    e = matplotlib.patches.Ellipse( (0,(x1+x3)/2), 2*x4, (x1-x3), fc='white', edgecolor='black', ec='none')
    ax.add_artist(e)
    e = matplotlib.patches.Ellipse( (0,(-x1+x2+x3)/2), 2*x5, (x1+x2+x3), fc='white', edgecolor='black', ec='none')
    ax.add_artist(e)
    
    # draw nose
    ax.plot([0,0], [-x6/2, x6/2], 'k')
    
    # draw mouth
    p = matplotlib.patches.Arc( (0,-x7+.5/x8), 1/x8, 1/x8, theta1=270-180/pi*arctan(x8*x9), theta2=270+180/pi*arctan(x8*x9))
    ax.add_artist(p)
    
    # draw eyes
    p = matplotlib.patches.Ellipse( (-x11-x14/2,x10), x14, x13*x14, angle=-180/pi*x12, facecolor='white', edgecolor='black')
    ax.add_artist(p)
    
    p = matplotlib.patches.Ellipse( (x11+x14/2,x10), x14, x13*x14, angle=180/pi*x12, facecolor='white', edgecolor='black')
    ax.add_artist(p)

    # draw pupils
    p = matplotlib.patches.Ellipse( (-x11-x14/2-x15*x14/2, x10), .05, .05, facecolor='black')
    ax.add_artist(p)
    p = matplotlib.patches.Ellipse( (x11+x14/2-x15*x14/2, x10), .05, .05, facecolor='black')
    ax.add_artist(p)
    
    # draw eyebrows
    ax.plot([-x11-x14/2-x14*x18/2,-x11-x14/2+x14*x18/2],[x10+x13*x14*(x16+x17),x10+x13*x14*(x16-x17)],'k')
    ax.plot([x11+x14/2+x14*x18/2,x11+x14/2-x14*x18/2],[x10+x13*x14*(x16+x17),x10+x13*x14*(x16-x17)],'k')

fig = plt.figure(figsize=(11,11))
for i in range(25):
    ax = fig.add_subplot(5,5,i+1,aspect='equal')
    cface(ax, .9, *rand(17))
    ax.axis([-1.2,1.2,-1.2,1.2])
    ax.set_xticks([])
    ax.set_yticks([])

fig.subplots_adjust(hspace=0, wspace=0)
plt.show()
*


*