Please enable Javascript to view the contents

Matplotlib 绘图实践

 ·  ☕ 3 分钟

概率分布

二项分布

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
import numpy as np
import matplotlib.pyplot as plt

from scipy.stats import binom 


def runplt(n: int, p: float, ax: plt.axes, fmt='yo', color='grey'):
    '''
    绘制单个二项分布的准备工作
    '''
    x = np.arange(n)
    y = [binom.pmf(x, n, p) for x in x]
    
    ax.plot(x, y, fmt, ms=5, mec='black', label='p={}\nn={}'.format(p, n))
    ax.vlines(x, 0, y, lw=5, color=color, alpha=0.5)
    ax.vlines(x, 0, y, lw=1, color=color)
    
    ax.set_xticks([x for x in range(0, n + 2, 2)])
    ax.legend(loc='best')


def main():
    '''
    绘制一组二项分布:参数对比
    '''
    # 参数
    ns = np.array([[10, 10, 10],
                   [10, 15, 20]])
    ps = np.array([[0.1, 0.5, 0.7],
                   [0.5, 0.5, 0.5]])
    
    # 绘图
    nrows = 2
    ncols = 3
    
    fig, axes = plt.subplots(nrows, ncols, figsize=(14, 7), sharey=True) 
    
    for i in range(nrows):
        for j in range(ncols):
            runplt(ns[i, j], ps[i, j], axes[i, j])
            
    fig.suptitle('PMF of Binomial Distribution') 
    plt.savefig('PMF-of-Binomial-distribution.svg')
    plt.show() 


if __name__ == '__main__':
    main()
二项分布

泊松分布

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
import numpy as np
import matplotlib.pyplot as plt

from scipy.stats import bernoulli, binom, multinomial, poisson


def main():
    '''
    泊松分布
    '''
    # 三组参数
    mus = [1, 4, 10]

    # 固定 x 的最大值
    x_max = int(poisson.ppf(0.99, np.max(mus) + 2))
    x = np.arange(x_max)

    fig, ax = plt.subplots()
    fmts = ['bo', 'ro', 'go']
    colors = [c[0] for c in fmts]
    
    for mu, fmt, color in zip(mus, fmts, colors):
        # 数据
        y = [poisson.pmf(x, mu) for x in x]
        
        # 绘图
        ax.plot(x, y, fmt, ms=5, mec='black', label='$\lambda$ = {}'.format(mu))
        ax.plot(x, y, c=color, alpha=0.5)

    ax.set_title('$X \sim Poisson(\lambda)$')
    ax.set_xlabel('x')
    ax.set_ylabel('$p(X=x)$')  
    ax.set_xticks([x for x in range(0, x_max, 5)])
    ax.legend(loc='best', frameon=True)
    plt.savefig('Poisson-distribution.svg')
    plt.show()
    

if __name__ == '__main__':
    main()
泊松分布

高斯分布

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import numpy as np
import matplotlib.pyplot as plt

from scipy.stats import norm


def main():
    '''
    高斯分布
    '''
    # 三组参数
    means = [0, 1, 0]
    variances = [1, 1, 0.5]
    
    x = np.linspace(-3, 4, 100)

    fig, ax = plt.subplots()
    
    for mean, variance in zip(means, variances):
        std = np.sqrt(variance)
        y = norm.pdf(x, loc=mean, scale=std)
        ax.plot(x, y, label='$\mu$={}, $\sigma^2$={}'.format(mean, variance))

    ax.set_title('$X \sim N(\mu, \sigma^2)$')
    ax.set_xlabel('x')
    ax.set_ylabel('$p(X=x)$')  
    ax.set_xticks([x for x in range(-3, 5)])
    ax.legend(loc='best', frameon=True)
    plt.savefig('Gaussian-distribution.svg')
    plt.show()


if __name__ == '__main__':
    main()
高斯分布

指数分布

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import numpy as np
import matplotlib.pyplot as plt

from scipy.stats import expon


def main():
    '''
    指数分布
    '''
    # 三组参数
    mus = [0.5, 1, 1.5]
    
    x_max = int(expon.ppf(0.99, 0, 1/np.min(mus)))
    x = np.linspace(0, x_max, 100)

    fig, ax = plt.subplots()
    
    for mu in mus:
        y = expon.pdf(x, loc=0, scale=1/mu)
        ax.plot(x, y, label='$\lambda$ = {}'.format(mu))

    ax.set_title('$X \sim Exp(\lambda)$')
    ax.set_xlabel('x')
    ax.set_ylabel('$p(X=x)$')  
    ax.set_xticks([x for x in range(x_max + 1)])
    ax.legend(loc='best', frameon=True)
    plt.savefig('Exponential-distribution.svg')
    plt.show()


if __name__ == '__main__':
    main()
指数分布

小功能

颜色填充

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0, 2 * np.pi, 100)
y = np.sin(x)

fig, ax = plt.subplots()

ax.plot(x, y, color='green')
ax.fill(x, y, facecolor='green', edgecolor=None, alpha=0.25)
ax.fill_between(x=x, y1=y+1, y2=y+2, color='lightskyblue', alpha=0.75)

plt.savefig('fill-and-fill_between.svg')
plt.show()
fill-and-fill_between

附:理解画布

figure 可以理解为整个画布,ax/axes 可以理解为具体的绘图区域(包括坐标轴、刻度、标题等)。
plt 直接绘制在整个画布上,ax/axes 绘制在自己的一亩三分地之中。因此稍微复杂的图都不建议直接使用 plt.

画一个

画复杂单图推荐。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0, 2 * np.pi, 50)
y = np.sin(x)

# 以下两种方式二选一
# 方式一
fig, ax = plt.subplots()

# # 方式二
# fig = plt.figure()
# ax = fig.add_subplot()

ax.plot(x, y-1)
ax.plot(x, y)
ax.plot(x, y+1)

plt.show()

画一组

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0, 2 * np.pi, 50)
y = np.sin(x)

# 配置画布:1x3
fig, axes = plt.subplots(nrows=1, ncols=3, figsize=(16, 6), sharey=True)
ax1, ax2, ax3 = axes

# 大标题
fig.suptitle('This is Figure', fontweight='bold')

# Axes
# Tip: 可以在以下三行中的任意一行后,测试直接 plt 的效果
ax1.plot(x, y-1, color='#4EACC5', label=r'$y=\sin(x)-1$')
ax2.plot(x, y, color='#FF9C34', label=r'$y=\sin(x)$')
ax3.plot(x, y+1, color='#4E9A06', label=r'$y=\sin(x)+1$')

# Axes 标题
ax1.set_title('This is Axes1')
ax2.set_title('This is Axes2')
ax3.set_title('This is Axes3')

# Axes 图例
ax1.legend(loc='best')
ax2.legend(loc='best')
ax3.legend(loc='best', frameon=False)

# Axes 轴标签和刻度
ax1.set_xlabel('xlabel')
ax1.set_ylabel('ylabel')
ax2.set_xticks([i for i in range(0, 7, 2)])
ax3.set_xticks(())

plt.savefig('multiple-axes.svg')
plt.show()
multiple-axes
分享

Molly Wang
作者
Molly Wang
一个数据产品人的自我修养