【python与数据分析】Matplotlib数据可视化(续)

目录

一、绘制箱线图

1.综述

2.boxplot函数

​编辑 3.单组数据箱线图

(1)代码

(2)结果

4.多组数据箱线图

(1)代码

(2)结果

二、绘制三维图形

1.综述

2.【例3.11】

(1)题目

(2)代码

(3)结果 

3.【例3.12】

(1)题目

(2)代码

(3)结果 

4.【例3.13】

(1)题目

(2)代码

(3)结果 

5.【例3.14】

(1)题目

(2)代码

(3)结果 

6.【例3.15】

(1)题目

(2)代码

(3)结果 

7.【例3.16】

(1)题目

(2)代码

(3)结果 

三、绘图区域切分——【例3.17】

1.题目

2.代码

3.结果 

四、设置图例样式

1.【例3.18】

(1)题目

(2)代码

(3)结果 

2.【例3.19】

(1)题目

(2)代码

(3)结果 

3.【例3.20】

(1)题目

(2)代码

(3)结果 

五、事件响应与处理

1.综述

2.【例3.21】

(1)题目

(2)代码

(3)结果

2.【例3.22】

(1)题目

(2)代码

(3)结果

3.【例3.23】

(1)题目

(2)代码

(3)结果

4.【例3.24】

(1)题目

(2)代码

(3)结果

5.【例3.25】

(1)题目

(2)代码

(3)结果

5'【例3.25代码改进】

(1)代码

(2)结果

6.【例3.26】

(1)题目

(2)代码

(3)结果

6'.【例3.26代码改进】

(1)代码

(2)结果

7.【例3.27】

(1)题目

(2)代码

(3)结果

8.【例3.28】

(1)题目

(2)代码

(3)结果

9.【例3.29】

(1)题目

(2)代码

(3)结果

10.【例3.30】

(1)题目

(2)代码

(3)结果

六、填充图形

1.【例3.31】

(1)题目

(2)代码

(3)结果

2.【例3.32】

(1)题目

(2)代码

(3)结果

七、保存绘图结果


一、绘制箱线图

1.综述

        箱线图(boxplot)也称箱须图,其绘制需要使用常用的统计量,能提供有关数据位置和分散情况的关键信息,尤其在比较不同特征时,更可表现其分散程度差异。

        箱线图利用数据中的五个统计量(最大值、下四分位数、中位数、上四分位数和最大值)来描述数据,他也可以粗略地看出数据是否具有对称性、分布的分散程度等信息,特别可以用于对几个样本的比较。

2.boxplot函数

 3.单组数据箱线图

(1)代码

from matplotlib import pyplot as plt
dataArray=[5,6,2,4,8,9,10,2,4,5,3,5,15]
plt.boxplot(dataArray,labels=["A"])
plt.title("Box-plot Test")
plt.savefig("a.png")
plt.show()

(2)结果

4.多组数据箱线图

(1)代码

from matplotlib import pyplot as plt

dataArray=[5,6,2,4,8,9,10,2,4,5,3,5,15]
dataArray2=[1,2,7,9,5,7,6,8,2,3,4,10,2,4,0]

plt.boxplot((dataArray,dataArray2),labels=["A","B"])

plt.title("Multi Box-plot Test")

plt.savefig("b.png")
plt.show()

(2)结果

二、绘制三维图形

1.综述

        如果要绘制三维图形,首先需要使用下面的语句导入相应的对象:

from mpl.toolkits.mplot3d import Axes3D

        然后使用下面的两种方式之一声明要创建三维子图:

ax=fig.gca(projection='3d')

ax=plt.subplot(111,projection='3d')

        接下来就可以使用ax的plot()方法绘制三维曲线、plot_surface()方法绘制三维曲面、scatter()方法绘制三维散点图或bar3d()方法绘制三维柱状图。

2.【例3.11】

(1)题目

(2)代码

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

# 绘制三维图形
fig = plt.figure()
ax = fig.gca(projection='3d')

# 生成测试数据
theta = np.linspace(-4 * np.pi, 4 * np.pi, 100)
z = np.linspace(-4, 4, 100)*0.3
r = z**4 + 1
x = r * np.sin(theta)
y = r * np.cos(theta)

# 绘制三维曲线,设置标签
ax.plot(x, y, z, 'rv-', label='参数曲线')

# 设置图例字体
font = fm.FontProperties(fname=r'C:\Windows\Fonts\STKAITI.ttf')
# 设置图例字号的一种方式
mpl.rcParams['legend.fontsize'] = 10
# 创建并显示图例
ax.legend(prop=font)

plt.show()

(3)结果 

3.【例3.12】

(1)题目

(2)代码

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

# 生成测试数据,在x和y方向分布生成-2到2之间的20个数
# 步长使用虚数,虚部表示点的个数,并且包含end
x, y = np.mgrid[-2:2:20j, -2:2:20j]
z = 50 * np.sin(x+y*2)

# 创建三维图形
ax = plt.subplot(111, projection='3d')
# 绘制三维曲面
ax.plot_surface(x,y,z,
                rstride=3, cstride=2,
                cmap=plt.cm.coolwarm)
# 设置坐标轴标签
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
# 设置图形标题
ax.set_title('三维曲面', fontproperties='simhei', fontsize=24)

plt.show()

(3)结果 

4.【例3.13】

(1)题目

(2)代码

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

# 生成测试数据
x = np.random.randint(0, 40, 10)
y = np.random.randint(0, 40, 10)
z = 80*abs(np.sin(x+y))

# 创建三维图形
ax = plt.subplot(projection='3d')
# 绘制三维柱状图
ax.bar3d(x,                 # 设置x轴数据
        y,                 # 设置y轴数据
          np.zeros_like(z), # 设置柱的z轴起始坐标为0
          dx=1,              # x方向的宽度
          dy=1,              # y方向的厚度
          dz=z,              # z方向的高度
          color='red')      # 设置面片颜色为红色

# 设置坐标轴标签
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')

plt.show()

(3)结果 

5.【例3.14】

(1)题目

(2)代码

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

x = np.random.randint(0, 40, 10)
y = np.random.randint(0, 40, 10)
z = 80*abs(np.sin(x+y))    
ax = plt.subplot(projection='3d')

for xx, yy, zz in zip(x, y, z):
    color = np.random.random(3)
    ax.bar3d(xx,
              yy,
              0,
              dx=1,
              dy=1,
              dz=zz,
              color=color)
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')

plt.show()

(3)结果 

6.【例3.15】

(1)题目

(2)代码

import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.font_manager as fm
import mpl_toolkits.mplot3d

# 创建DataFrame结构
df = pd.DataFrame({'男性':(450,800,200),
                     '女性':(150,100,300)})
# 创建三维图形
ax = plt.subplot(projection='3d')

# 绘制三维柱状图
ax.bar3d([0]*3, range(3), [0]*3,
          0.1, 0.1, df['男性'].values,
          color='r')
ax.bar3d([1]*3, range(3), [0]*3,
          0.1, 0.1, df['女性'].values,
          color='b')

# 设置坐标轴刻度和文本
ax.set_xticks([0,1])
ax.set_xticklabels(['男性','女性'], fontproperties='simhei')
ax.set_yticks([0,1,2])
ax.set_yticklabels(['从不闯红灯','跟从别人闯红灯','带头闯红灯'],
                     fontproperties='simhei')
# 设置z轴标签
ax.set_zlabel('人数', fontproperties='simhei')

plt.show()

(3)结果 

7.【例3.16】

(1)题目

(2)代码

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

# 生成测试数据
x = np.random.randint(0, 40, 30)
y = np.random.randint(0, 40, 30)
z = np.random.randint(0, 40, 30)

# 创建三维图形
ax = plt.subplot(projection='3d')
# 绘制三维柱状图
for xx, yy, zz in zip(x,y,z):
    color = 'r'
    if 10<zz<20:
        color = 'b'
    elif zz>=20:
        color = 'g'
    ax.scatter(xx, yy, zz, c=color, marker='*',
                s=160, linewidth=1, edgecolor='b')

# 设置坐标轴标签和图形标题
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
ax.set_title('三维散点图', fontproperties='simhei', fontsize=24)

plt.show()

(3)结果 

三、绘图区域切分——【例3.17】

1.题目

2.代码

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

ax1 = plt.subplot(241)
# 在子图中绘制极坐标图
ax2 = plt.subplot(242, projection='polar')
ax3 = plt.subplot(243, projection='polar')
# 设置polar=True,等价于设置projection='polar'
ax4 = plt.subplot(244, polar=True)
# 在子图中绘制三维图形
ax5 = plt.subplot(212, projection='3d')

# 紧缩四周空白,扩大绘图面积,设置子图之间的水平距离与垂直距离
plt.tight_layout()
plt.subplots_adjust(wspace=0.1, hspace=0.2)

# 测试数据
r = np.arange(1, 6, 1)
theta = (r-1) * (np.pi/2)
x = np.arange(1, 7, 0.5)
y = np.linspace(1, 3, 12)
z = 20*np.sin(x+y)

# 在不同子图中绘制图形
ax1.plot(theta, r, 'b--D')
ax2.plot(theta, r, linewidth=3, color='r')
ax3.scatter(theta, r, marker='*', c='g', s=60)
ax4.bar(theta, r)
ax5.plot(x, y, z)

plt.show()

3.结果 

四、设置图例样式

1.【例3.18】

(1)题目

(2)代码

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.font_manager as fm

t = np.arange(0.0, 2*np.pi, 0.01)
s = np.sin(t)
c = np.cos(t)

plt.plot(t, s, label='正弦')
plt.plot(t, c, label='余弦')
plt.title('sin-cos函数图像',         #标题文本
          fontproperties='STLITI',  #标题字体
          fontsize=24)               #标题字号
plt.xlabel('x坐标', fontproperties='simhei', fontsize=18)
plt.ylabel('正弦余弦值', fontproperties='simhei', fontsize=18)

myfont = fm.FontProperties(fname=r'C:\Windows\Fonts\STKAITI.ttf')
plt.legend(prop=myfont,              #图例字体
           title='Legend',           #图例标题
           loc='lower left',         #图例左下角坐标为(0.43,0.75)
           bbox_to_anchor=(0.43,0.75),
           shadow=True,               #显示阴影
           facecolor='yellowgreen',  #图例背景色
           edgecolor='red',           #图例边框颜色
           ncol=2,                     #显示为两列
           markerfirst=False)         #图例文字在前,符号在后

plt.show()

(3)结果 

2.【例3.19】

(1)题目

(2)代码

import matplotlib.pyplot as plt
import numpy as np

# 生成模拟数据
x = np.arange(0, 2*np.pi, 0.1)
y1 = np.sin(x)
y2 = np.cos(x)

# 创建图形,切分绘图区域,绘制两条曲线
fig = plt.figure(1)
ax1 = plt.subplot(211)
ax2 = plt.subplot(212)
l1, = ax1.plot(x, y1, 'r--')
l2, = ax2.plot(x, y2, 'b-.')

# 设置并显示图例,使用bbox_to_anchor参数使图例显示于子图之外
plt.legend([l1, l2],                       # 需要显示图例的两条曲线
           ['sin curve', 'cos curve'],   # 图例中与两条曲线对应的文本
           loc='lower right',             # 图例右下角位置
           bbox_to_anchor=(1, 2.2))

plt.show()

(3)结果 

3.【例3.20】

(1)题目

(2)代码

import numpy as np
import matplotlib.pyplot as plt

# 生成模拟数据
x = np.arange(0, 2*np.pi, 0.1)
y1 = np.sin(x)
y2 = np.cos(x)

# 绘制两条曲线
sin, = plt.plot(x, y1, 'r--')
cos, = plt.plot(x, y2, 'b-.')

# 创建第一个图例
legend1 = plt.legend([sin,cos],
                       ['sin','cos'],
                       loc='lower right')

x1 = np.random.randint(0, 6, 10)
x2 = np.random.randint(0, 6, 10)
y1 = np.random.randint(2, 5, 10)
y2 = np.random.randint(2, 5, 10)

# 绘制两个散点图
scatter1 = plt.scatter(x1, y1, s=20, c='r', marker='*')
scatter2 = plt.scatter(x2, y2, s=30, c='b', marker='v')

# 创建第二个图例
plt.legend([scatter1,scatter2],
            ['red scatter','blue scatter'],
            loc='lower right',
            bbox_to_anchor=(1, 0.5))
# 增加第一个图例
plt.gca().add_artist(legend1)

plt.show()

(3)结果 

五、事件响应与处理

1.综述

        matplotlib中有一个事件绑定函数fig.canvas.mpl_connect(),要接受事件,需要编写一个回调函数,然后将函数连接到事件管理器,就可相应与处理相应事件了。

        以下是可以连接到的事件及分类说明。

2.【例3.21】

(1)题目

(2)代码

import numpy as np
import matplotlib.pyplot as plt

def onMotion(event):
    # 获取鼠标位置和标注可见性
    x = event.xdata
    y = event.ydata
    visible = annot.get_visible()
    if event.inaxes == ax:
        # 测试鼠标事件是否发生在曲线上
        contain, _ = sinCurve.contains(event)
        if contain:
            # 设置标注的终点和文本位置,设置标注可见
            annot.xy = (x, y)
            annot.set_text(str(y))   # 设置标注文本
            annot.set_visible(True)  # 设置标注可见
        else:
            # 鼠标不在曲线附近,设置标注为不可见
            if visible:
                annot.set_visible(False)
        event.canvas.draw_idle()
        
def onEnter(event):
    # 鼠标进入时修改轴的颜色
    event.inaxes.patch.set_facecolor('yellow')
    event.canvas.draw_idle()

def onLeave(event):
    # 鼠标离开时恢复轴的颜色
    event.inaxes.patch.set_facecolor('white')
    event.canvas.draw_idle()
    
fig = plt.figure()
ax = fig.gca()
x = np.arange(0, 2*np.pi, 0.01)
y = np.sin(x)
sinCurve, = plt.plot(x, y,      # 绘图数据
                     picker=2)  # 鼠标距离曲线2个像素可识别
# 创建标注对象
annot = ax.annotate("",
                    xy=(0,0),                     # 箭头位置
                    xytext=(-50,50),             # 文本相对位置
                    # 相对于xy的偏移量单位
                    textcoords="offset pixels",
                    # 圆角,红色背景
                    bbox=dict(boxstyle="round", fc="r", alpha=0.4),
                    # 标注箭头形状
                    arrowprops=dict(arrowstyle="<->"))
annot.set_visible(False)

# 添加事件处理函数
fig.canvas.mpl_connect('motion_notify_event', onMotion)  
fig.canvas.mpl_connect('axes_enter_event', onEnter)
fig.canvas.mpl_connect('axes_leave_event', onLeave)

plt.show()

(3)结果

2.【例3.22】

(1)题目

(2)代码

from math import sin
import numpy as np
import matplotlib.pyplot as plt
 
fig = plt.figure()

# 存放所有顶点的标注信息
annotations = []

# 绘制顶点并创建标注信息
xx = np.arange(0, 4*np.pi, 0.5)
for x in xx:
    y = sin(x)
    # 依次绘制正弦曲线上的每个顶点
    point, = plt.plot(x, y, 'bD', markersize=5)
    # 为每个顶点创建隐藏的文本标注
    # 参数xy表示标注箭头指向的位置,xytext表示文本起始坐标
    # 参数arrowprops表示箭头样式
    # 参数bbox表示标注文本的背景色以及边框样式
    annot = plt.annotate('x=%f,y=%f'%(x,y),
                           xy=(x+0.1, y+0.03), xycoords='data',
                           xytext=(x-2, y+0.2), textcoords='data',
                           arrowprops={'arrowstyle':'->',
                                  'connectionstyle':"arc3,rad=0.5"},
                           bbox={'boxstyle':'round',
                                  'facecolor':'r',
                                  'alpha':0.2},
                           visible=False
                         )
    annotations.append([point, annot])
 
def onMouseMove(event):
    changed = False
    # 遍历所有顶点,检查鼠标当前位置是否与某个顶点足够接近
    # 把足够接近的顶点的标注设置为可见,其他顶点的标注不可见
    for point, annotation in annotations:
        visible = (point.contains(event)[0] == True)
        if visible != annotation.get_visible():
            annotation.set_visible(visible)
            changed = True
    if changed:
        # 只在某顶点标注的可见性发生改变之后才更新画布
        plt.draw()

# 响应并处理鼠标移动事件 
fig.canvas.mpl_connect('motion_notify_event', onMouseMove)
 
plt.show()

(3)结果

3.【例3.23】

(1)题目

(2)代码

from itertools import cycle
import matplotlib.pyplot as plt

# 存储鼠标依次单击的位置
x = []
y = []
# 可用颜色和当前颜色
colors = cycle('rgbcmyk')
color = next(colors)

def onMouseClick(event):
    global color
    if event.button == 1:
        # 单击鼠标左键,绘制新直线
        x.append(event.xdata)
        y.append(event.ydata)
        if len(x) > 1:
            plt.plot([x[-2],x[-1]], [y[-2],y[-1]], c=color, lw=2)
        plt.xticks(range(10))
        plt.yticks(range(10))
    elif event.button == 3:
        # 单击鼠标右键,切换颜色
        color = next(colors)
    elif event.button == 2:
        # 单击鼠标中键,删除最后绘制的一个图形
        if ax.lines:
            del ax.lines[-1]
            x.pop()
            y.pop()
    event.canvas.draw()
        
def onClose(event):
    print('closed')

def onClear(event):
    # 按下键盘上的c,清除所有已绘制图形
    if event.key == 'c':
        ax.lines.clear()
        x.clear()
        y.clear()
        # 更新图形画布
        event.canvas.draw()

# 创建图形
fig = plt.figure()
ax = plt.gca()
plt.xticks(range(10))
plt.yticks(range(10))

# 设置响应并处理事件的函数
fig.canvas.mpl_connect('button_press_event', onMouseClick)
fig.canvas.mpl_connect('key_press_event', onClear)
fig.canvas.mpl_connect('close_event', onClose)

plt.show()

(3)结果

4.【例3.24】

(1)题目

(2)代码

import matplotlib.pyplot as plt

# 存储鼠标依次经过的位置
x = []
y = []

def onMouseClick(event):
    if event.button == 1:
        # 单击鼠标左键,绘制新直线
        x.clear()
        y.clear()
        x.append(event.xdata)
        y.append(event.ydata)

def onMouseMove(event):
    x.append(event.xdata)
    y.append(event.ydata)
    if event.button==1 and len(x)>1:
        plt.plot([x[-2],x[-1]], [y[-2],y[-1]], c='r', lw=2)
    event.canvas.draw()
        
# 创建图形
fig = plt.figure()
ax = plt.gca()
plt.xlim(0, 10)
plt.ylim(0, 10)

# 设置响应并处理事件的函数
fig.canvas.mpl_connect('button_press_event', onMouseClick)
fig.canvas.mpl_connect('motion_notify_event', onMouseMove)

plt.show()

(3)结果

5.【例3.25】

(1)题目

(2)代码

import matplotlib.pyplot as plt

def onMouseDown(event):
    if event.button == 1:
        # 单击鼠标左键,绘制新直线,记录直线起点坐标
        global x0, y0
        x0 = event.xdata
        y0 = event.ydata

def onMouseMove(event):
    global x1, y1
    x1 = event.xdata
    y1 = event.ydata
    if event.button==1:
        # 删除最后绘制的一条直线
        if len(ax.lines)>1:
            del ax.lines[-1]
        # 从起点到当前位置绘制一条直线
        plt.plot([x0,x1], [y0,y1], c='r', lw=2)
        # 更新标注对象的当前位置
        annot.xy = (x1, y1)
        # 计算并显示当前位置与按下鼠标的位置的距离
        distance = (((x0-x1)**2 + (y0-y1)**2) ** 0.5)
        distance = round(distance,2)
        annot.set_text(str((distance)))
        # 设置标注对象可见
        annot.set_visible(True)
        event.canvas.draw()

def onMouseUp(event):
    # 隐藏标注对象
    annot.set_visible(False)
    if event.button == 1:
        plt.plot([x0,x1], [y0,y1], c='r', lw=2)
        event.canvas.draw()
        
# 创建图形
fig = plt.figure()
ax = plt.gca()
im = plt.imread('sample.jpg')
plt.imshow(im)

# 创建标注对象
annot = ax.annotate("",
                    xy=(0,0),              # 箭头位置
                    xytext=(-10,10),       # 文本相对位置
                    # 相对于xy的偏移量单位
                    textcoords="offset pixels")
annot.set_visible(False)

# 设置响应并处理事件的函数
fig.canvas.mpl_connect('button_press_event', onMouseDown)
fig.canvas.mpl_connect('motion_notify_event', onMouseMove)
fig.canvas.mpl_connect('button_release_event', onMouseUp)

plt.show()

(3)结果

5'【例3.25代码改进】

(1)代码

import matplotlib.pyplot as plt

def onMouseDown(event):
    if event.button == 1:
        # 单击鼠标左键,绘制新直线,记录直线起点坐标
        global x0, y0
        x0 = event.xdata
        y0 = event.ydata

def onMouseMove(event):
    global x1, y1
    x1 = event.xdata
    y1 = event.ydata
    if event.button==1:
        # 删除最后绘制的一条直线
        if len(ax.lines)>1:
            del ax.lines[-1]
        # 从起点到当前位置绘制一条直线
        plt.plot([x0,x1], [y0,y1], c='r', lw=2)
        # 更新标注对象的当前位置
        annot.xy = (x1, y1)
        # 计算并显示当前位置与按下鼠标的位置的距离
        distance = (((x0-x1)**2 + (y0-y1)**2) ** 0.5)
        distance = round(distance,2)
        annot.set_text(str((distance)))
        # 设置标注对象可见
        annot.set_visible(True)
        event.canvas.draw()

def onMouseUp(event):
    # 隐藏标注对象
    annot.set_visible(False)
    if event.button == 1:
        ax.lines.clear()
        event.canvas.draw()
        
# 创建图形
fig = plt.figure()
ax = plt.gca()
im = plt.imread('sample.jpg')
plt.imshow(im)

# 创建标注对象
annot = ax.annotate("",
                    xy=(0,0),              # 箭头位置
                    xytext=(-10,10),       # 文本相对位置
                    # 相对于xy的偏移量单位
                    textcoords="offset pixels")
annot.set_visible(False)

# 设置响应并处理事件的函数
fig.canvas.mpl_connect('button_press_event', onMouseDown)
fig.canvas.mpl_connect('motion_notify_event', onMouseMove)
fig.canvas.mpl_connect('button_release_event', onMouseUp)

plt.show()

(2)结果

【注】线画上后,松开鼠标,线立刻消失 

6.【例3.26】

(1)题目

(2)代码

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

# 忽略警告信息
warnings.filterwarnings("ignore",".*GUI is implemented.*")

# 测试数据
x = np.arange(1, 13)
y = np.random.randint(10, 30, 12)
for i in range(20):
    # 清除当前轴域
    plt.cla()
    # 绘制水平柱状图
    plt.barh(x, y)
    plt.title('20%02d年'%i, fontproperties='simhei',fontsize=20)
    plt.yticks(x, list(map(lambda i: '%d月'%i, x)),
                fontproperties='simhei')
    plt.xticks(list(range(0,100,10)))
    # 暂停0.5秒
    plt.pause(0.5)
    # 更新数据
    y = y+np.random.randint(0, 5, 12)
    
plt.show()

(3)结果

【注】结果是一个动态过程。

6'.【例3.26代码改进】

(1)代码

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

# 忽略警告信息
warnings.filterwarnings("ignore",".*GUI is implemented.*")

# 测试数据
x = np.arange(1, 13)
y = np.random.randint(1, 30, 12)
for i in range(20):
    # 清除当前轴域
    plt.cla()
    # 绘制水平柱状图
    temp = sorted(zip(x,y), key=lambda item:item[1])
    x = [item[0] for item in temp]
    y = [item[1] for item in temp]
    plt.barh(range(1,13), y)
    plt.title('20%02d年'%i, fontproperties='simhei',fontsize=20)
    plt.yticks(range(1,13), list(map(lambda i: '%d月'%i, x)),
               fontproperties='simhei')
    plt.xticks(list(range(0,160,20)))
    for xx, yy in zip(range(1,13),y):
        plt.text(yy+0.1, xx-0.1, str(yy))
    # 暂停0.5秒
    plt.pause(0.5)
    # 更新数据
    y = y+np.random.randint(0, 10, 12)
    
plt.show()

(2)结果

7.【例3.27】

(1)题目

(2)代码

from time import sleep
from threading import Thread
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import Button

fig, ax = plt.subplots()
# 设置图形显示位置
plt.subplots_adjust(bottom=0.2)

# 实验数据
range_start, range_end, range_step = 0, 1, 0.005
t = np.arange(range_start, range_end, range_step)
s = np.sin(4*np.pi*t)
l, = plt.plot(t, s, lw=2)

# 自定义类,用来封装两个按钮的单击事件处理函数
class ButtonHandler:
    def __init__(self):
        self.flag = False
        self.range_s, self.range_e, self.range_step = 0, 1, 0.005
        
    # 线程函数,用来更新数据并重新绘制图形
    def threadStart(self):
        while self.flag:
            sleep(0.02)
            self.range_s += self.range_step
            self.range_e += self.range_step
            t = np.arange(self.range_s, self.range_e,
                           self.range_step)
            ydata = np.sin(4*np.pi*t)
            # 更新数据
            l.set_ydata(ydata)
            # 重新绘制图形
            plt.draw()
            
    def Start(self, event):
        if not self.flag:
            self.flag = True
            # 创建并启动新线程
            t = Thread(target=self.threadStart)
            t.start()
        
    def Stop(self, event):
        if self.flag:
            self.flag = False
        
callback = ButtonHandler()

# 创建按钮并设置单击事件处理函数
axnext = plt.axes([0.7, 0.05, 0.1, 0.075])
btnStart = Button(axnext, 'Start', color='0.7', hovercolor='r')
btnStart.on_clicked(callback.Start)

axprev = plt.axes([0.81, 0.05, 0.1, 0.075])
btnStop = Button(axprev, 'Stop')
btnStop.on_clicked(callback.Stop)

plt.show()

(3)结果

8.【例3.28】

(1)题目

(2)代码

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import Slider, Button, RadioButtons

fig, ax = plt.subplots()
plt.subplots_adjust(left=0.1, bottom=0.25)
t = np.arange(0.0, 1.0, 0.001)

# 初始振幅与频率,并绘制初始图形
a0, f0 = 5, 3
s = a0*np.sin(2*np.pi*f0*t)
l, = plt.plot(t, s, lw=2, color='red')
# 设置坐标轴刻度范围
plt.axis([0, 1, -10, 10])

axColor = 'lightgoldenrodyellow'
# 创建两个Slider组件,分别设置位置/尺寸、背景色和初始值
axfreq = plt.axes([0.1, 0.1, 0.75, 0.03], facecolor=axColor)
sfreq = Slider(axfreq, 'Freq', 0.1, 30.0, valinit=f0)
axamp = plt.axes([0.1, 0.15, 0.75, 0.03], facecolor=axColor)
samp = Slider(axamp, 'Amp', 0.1, 10.0, valinit=a0)

# 为Slider组件设置事件处理函数
def update(event):
    # 获取两个Slider组件的当前值,并以此来更新图形
    amp = samp.val
    freq = sfreq.val
    l.set_ydata(amp*np.sin(2*np.pi*freq*t))
    plt.draw()
sfreq.on_changed(update)
samp.on_changed(update)

# 调整Slider值和曲线形状的按钮
def adjustSliderValue(event):
    ampValue = samp.val + 0.05
    if ampValue > 10:
        ampValue = 0.1
    samp.set_val(ampValue)

    freqValue = sfreq.val + 0.05
    if freqValue > 30:
        freqValue = 0.1
    sfreq.set_val(freqValue)
    update(event)
axAdjust = plt.axes([0.6, 0.025, 0.1, 0.04])
buttonAdjust = Button(axAdjust, 'Adjust', color=axColor,
                      hovercolor='red')
buttonAdjust.on_clicked(adjustSliderValue)

# 创建按钮组件,用来恢复初始值
resetax = plt.axes([0.8, 0.025, 0.1, 0.04])
button = Button(resetax, 'Reset', color=axColor,
                hovercolor='yellow')
def reset(event):
    sfreq.reset()
    samp.reset()
button.on_clicked(reset)

plt.show()

(3)结果

9.【例3.29】

(1)题目

(2)代码

from random import choice
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import RadioButtons, Button

# 3中不同频率的信号
t = np.arange(0.0, 2.0, 0.01)
s0 = np.sin(2*np.pi*t)
s1 = np.sin(4*np.pi*t)
s2 = np.sin(8*np.pi*t)

# 创建图形
fig, ax = plt.subplots()
l, = ax.plot(t, s0, lw=2, color='red')
plt.subplots_adjust(left=0.3)

# 定义允许的几种频率,并创建单选钮组件
# 其中[0.05, 0.7, 0.15, 0.15]表示组件在窗口上的归一化位置
axcolor = '#886699'
rax = plt.axes([0.05, 0.7, 0.15, 0.15], facecolor=axcolor)
radio = RadioButtons(rax, ('2 Hz', '4 Hz', '8 Hz'))
hzdict = {'2 Hz': s0, '4 Hz': s1, '8 Hz': s2}

def hzfunc(label):
    ydata = hzdict[label]
    l.set_ydata(ydata)
    plt.draw()
radio.on_clicked(hzfunc)

# 定义允许的几种颜色,并创建单选钮组件
rax = plt.axes([0.05, 0.4, 0.15, 0.15], facecolor=axcolor)
colors = ('red', 'blue', 'green')
radio2 = RadioButtons(rax, colors)
def colorfunc(label):
    l.set_color(label)
    plt.draw()
radio2.on_clicked(colorfunc)

# 定义允许的几种线型,并创建单选钮组件
rax = plt.axes([0.05, 0.1, 0.15, 0.15], facecolor=axcolor)
styles = ('-', '--', '-.', 'steps', ':')
radio3 = RadioButtons(rax, styles)
def stylefunc(label):
    l.set_linestyle(label)
    plt.draw()
radio3.on_clicked(stylefunc)

# 定义按钮单击事件处理函数,并在窗口上创建按钮
def randomFig(event):
    # 随机选择一个频率,同时设置单选钮的选中项
    hz = choice(tuple(hzdict.keys()))
    hzLabels = [label.get_text() for label in radio.labels]
    radio.set_active(hzLabels.index(hz))
    l.set_ydata(hzdict[hz])
    
    # 随机选择一个颜色,同时设置单选钮的选中项
    c = choice(colors)
    radio2.set_active(colors.index(c))
    l.set_color(c)
    
    # 随机选择一个线型,同时设置单选钮的选中项
    style = choice(styles)
    radio3.set_active(styles.index(style))
    l.set_linestyle(style)
    
    # 根据设置的属性绘制图形
    plt.draw()
axRnd = plt.axes([0.5, 0.015, 0.2, 0.045])
buttonRnd = Button(axRnd, 'Random Figure', color='0.6', hovercolor='r')
buttonRnd.on_clicked(randomFig)

# 显示图形
plt.show()

(3)结果

10.【例3.30】

(1)题目

(2)代码

import numpy as np
import matplotlib.pyplot as plt

fig = plt.figure()
ax = fig.gca()

x = np.arange(0, 4*np.pi, 0.3)
y = np.sin(x)
ax.plot(x, y, 'r-*', picker=5)

def onpick(event):
    thisline = event.artist
    xdata = thisline.get_xdata()
    ydata = thisline.get_ydata()
    ind = event.ind
    points = tuple(zip(xdata[ind], ydata[ind]))
    print('顶点编号:{}\n坐标:{}'.format(ind[0], points))

fig.canvas.mpl_connect('pick_event', onpick)

plt.show()

(3)结果

 【注】点击哪个点,就显示哪个点的坐标

六、填充图形

1.【例3.31】

(1)题目

(2)代码

import numpy as np
import matplotlib.pyplot as plt

# 生成模拟数据
x = np.arange(0.0, 4.0*np.pi, 0.01)
y = np.sin(x)

# 绘制正弦曲线
plt.plot(x, y)
# 绘制基准水平直线
plt.plot((x.min(),x.max()), (0,0), 'r', lw=2)
# 设置坐标轴标签
plt.xlabel('x')
plt.ylabel('y')
# 填充指定区域
plt.fill_between(x, y,
                   where=(2.3<x) & (x<4.3) | (x>10),
                   facecolor='purple')
# 可以填充多次
plt.fill_between(x, y,
                   where=(7<x) & (x<8),
                   facecolor='green')

plt.show()

(3)结果

2.【例3.32】

(1)题目

(2)代码

import numpy as np
import matplotlib.pyplot as plt

# 生成模拟数据
x = np.arange(0.0, 4.0*np.pi, 0.01)
y = np.sin(x)
z = np.cos(x)

# 绘制正弦曲线
plt.plot(x, y, 'r', lw=2)
plt.plot(x, z, 'g', lw=2)
# 绘制基准水平直线
plt.plot((x.min(),x.max()), (0,0))
# 设置坐标轴标签
plt.xlabel('x')
plt.ylabel('y')

# 填充正弦曲线与余弦曲线之间的部分
plt.fill_between(x, y, z, facecolor='purple', hatch='o')

plt.show()

(3)结果

七、保存绘图结果


  • 2
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值