目录
一、绘制箱线图
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()