山东大学Python(11)——Matplotlib

#%%
# 使用 jupyter notebook 编写
"""
本章知识目录:
    1.制作函数曲线
    2.线宽、线型、网格线控制
    3.坐标轴、图标识
    4.设定坐标轴刻度
    5.设置样例legend
    6.显示汉字
    7.快速绘图
    8.plot函数
    9.保存绘图
    10.绘制多轴图
    11.axes对象的切换
    12.绘图函数——对数坐标图
    13.绘图函数——柱状坐标图
    14.绘图函数——直方图
    15.绘图函数——散列图
    16.绘图函数——图像
    17.绘图函数——显示热图
    18.绘图函数——ogrid函数
    19.绘图函数——三维绘图
    20.绘图函数——投影简介
"""

"""
考试:
展示的方法
特别关注的是画二维和三维曲线
如何去控制这些
整个PPT都有可能考
"""

import matplotlib.pyplot as plt
import numpy as np

#%%

"""
制作函数曲线:
    引用、准备数据、制图、显示图形
"""
# step 1 引用
import matplotlib.pyplot as plt
import numpy as np
# step 2 准备数据
x=np.arange(-np.pi,np.pi,0.1)
y=np.sin(x)
# step 3 制图
plt.plot(x,y,'b--')  # ‘b’代表使用蓝色画曲线
# step 4 显示图形
# plt.grid(True) # 可以尝试加上这句话,是否绘制网格
plt.show()

#%%

"""
线宽、线型、网格线控制:
    第三个参数:https://blog.csdn.net/cjcrxzz/article/details/79627483
"""
# 在plot中直接设定 
sin, cos = np.sin(x), np.cos(x)
plt.plot(x,sin,color='blue',linewidth=10.0, linestyle='-') 
# 设置蓝色、2像素宽划线
plt.plot(x,cos,color='red',linewidth=2.0, linestyle='-.') 
# 用虚线画图
plt.grid(True)
# 画网格线

#%%

"""
坐标轴、图标识:
    使用xlim(x1, x2)设定横轴坐标范围,ylim(y1, y2)设置纵轴坐标范围
"""
x=np.arange(-5,5,0.1)
y=x**2
plt.xlim(-5,5) # 设定横坐标范围
plt.ylim(0,100)  # 设定纵坐标范围
plt.xlabel("x")  # 横轴标识
plt.ylabel("y=x*x") # 纵轴标识
plt.title("Plot  y=x*x") # 设定图形的标题
plt.plot(x,y)
plt.show()

#%%

"""
设定坐标轴刻度:
    特别指定坐标轴的刻度,制作更能表达深意的图形,xticks(yticks)方法实现了该功能
"""
# from pylab import *
import pylab as plb
x = np.linspace(-np.pi,np.pi,100)
cos = np.cos(x)
plb.xticks(np.linspace(-np.pi,np.pi,5))
plt.plot(x,cos,color='red',linewidth=2.0, linestyle='-')
plt.show() # plb或者plt都可以使用.plot和.show

#%%

"""
设置样例legend:
    https://blog.csdn.net/helunqu2017/article/details/78641290
"""
import numpy as np
from pylab import *
x=np.linspace(-np.pi,np.pi,100)
sin,cos = np.sin(x), np.cos(x)
plot(x,sin,color='blue',linewidth=2.0, linestyle='-',label='sin')
plot(x,cos,color='red',linewidth=2.0, linestyle='-',label='cos')
plt.legend(["sin", "余弦"], loc="upper right") # 汉字没什么问题
show()

#%%

"""
显示汉字:
    默认,汉字会乱码(但上面的测试中,没有显示乱码)
"""
import matplotlib as mpl
mpl.rcParams['font.family'] = 'sans-serif'
mpl.rcParams['font.sans-serif'] = [u'SimHei']

#%%

"""
快速绘图:
     matplotlib中的快速绘图的函数库可以通过如下语句载入:
     import matplotlib as plt
     接下来调用figure创建一个绘图对象,并且使它成为当前的绘图对象。
     plt.figure(figsize=(8,4))
     通过figsize参数可以指定绘图对象的宽度和高度,单位为英寸;
     dpi参数指定绘图对象的分辨率,即每英寸多少个像素,缺省值为80。
     因此本例中所创建的图表窗口的长度为8*80 = 640像素。
     def figure(num=None, figsize=None, dpi=None, 
     facecolor=None, edgecolor=None, frameon=True, 
     FigureClass=Figure, clear=False, **kwargs)
"""

#%%

"""
figure参数num:
    如果此参数没有提供,则一个新的figure对象将被创建,
同时增加figure的计数数值,此数值被保存在figure对象的一个数字属性当中。
    如果有此参数,
存在对应id的figure对象,则激活对应id的figure对象。
如果对应id的figur对象不存在,则创建它并返回它。
如果num的值是字符串,则将窗口标题设置为此字符串

建立了两个figure图,plt.xlim,plt.ylim
只给最后创建的figure(fig2)配置,
可以通过Num参数对第一个figure的相关属性进行配置。(看PPT上的代码)
"""
fig1 = plt.figure(num="3*1 inches", figsize=(3, 1))
fig2 = plt.figure(num="6*2 inches", figsize=(6, 2))
plt.show()
plt.close

#%%

"""
plot函数:
    plt.plot(x,y,format_string,**kwargs)
    xx:轴数据,列表或数组,可选
    y:y轴数据,列表或数组
    format_string:控制曲线的格式字符串,可选
    **kwargs:第二组或更多(x,y,format_string)
    
    label : 给所绘制的曲线一个名字,此名字在图示(legend)中显示。
        只要在字符串前后添加''$''符号,
        matplotlib就会使用其内嵌的latex引擎绘制的数学公式。
    color : 指定曲线的颜色
    linewidth : 指定曲线的宽度
    xlabel / ylabel : 设置X轴/Y轴的文字
    title : 设置图表的标题
    xlim / ylim : 设置X轴/Y轴的范围
    legend : 显示图示
    最后调用plt.show()显示出创建的所有绘图对象
"""
# 当绘制多条曲线时,各条曲线的x不能省略
import matplotlib.pyplot as plt 
import numpy as np 
a = np.arange(10)
plt.plot(a,a*1.5,a,a*2.5,a,a*3.5,a,a*4.5) 
plt.show()

#%%

# format_string控制颜色字符,风格字符,标记字符PPT第23页
a = np.arange(10)
plt.plot(a,a*1.5,'go-',a,a*2.5,'rx',a,a*3.5,'*',a,a*4.5,'b-.')
plt.show()

#%%

x = np.linspace(0, 10, 1000)
y = np.sin(x)
z = np.cos(x**2) 
plt.figure(figsize=(8,4))
plt.plot(x,y,label="$sin(x)$",color="red",linewidth=2) 
plt.plot(x,z,"b--",label="$cos(x^2)$") 
plt.xlabel("Time(s)") 
plt.ylabel("Volt") 
plt.title("PyPlot First Example") 
plt.ylim(-1.2,1.2) 
plt.legend() 
plt.savefig("test2.png") # 这句话放在前面没有问题,放在show的后面图片就是空白
plt.show()

#%%

"""
绘制多轴图:
    1.一个绘图对象(figure)可以包含多个轴(axis),
    在Matplotlib中用轴表示一个绘图区域,可以将其理解为子图。
    2.可以使用subplot函数快速绘制有多个轴的图表。
    3.subplot函数的调用形式如下:
        subplot(numRows, numCols, plotNum)
    3.subplot将整个绘图区域等分为numRows行和 numCols列个子区域,
    然后按照从左到右,从上到下的顺序对每个子区域进行编号,
    左上的子区域的编号为1。
    4.如果numRows,numCols和plotNum这三个数都小于10的话,
    可以把它们缩写为一个整数,例如subplot(323)和subplot(3,2,3)是相同的。
    5.subplot在plotNum指定的区域中创建一个轴对象。
    如果新创建的轴和之前创建的轴重叠的话,之前的轴将被删除。

"""
color = ['r', 'g', 'b', 'y', 'c', 'k']
for i in range(4):
    plt.subplot(221+i)
plt.show()

#%%

"""
axes对象的切换:
    1.subplot()返回它所创建的Axes对象,可以将它用变量保存起来,
    然后用sca()交替让它们成为当前Axes对象,并调用plot()在其中绘图。
    2.首先通过figure()创建了两个图表,它们的序号分别为1和2。
    然后在图表2中创建了上下并排的两个子图,并用变量ax1和ax2保存。
    3.在循环中,先调用figure(1)让图表1成为当前图表,并在其中绘图。
    然后调用sca(ax1) 和sca(ax2)分别让子图ax1和ax2成为当前子图,并在其中绘图。
    4.当它们成为当前子图时,包含它们的图表2也自动成为当前图表,
    因此不需要调用figure(2)依次在图表1和图表2的两 个子图之间切换,
    逐步在其中添加新的曲线
"""
plt.figure(1) # 创建图表1
plt.figure(2) # 创建图表2
ax1 = plt.subplot(211) # 在图表2中创建子图1
ax2 = plt.subplot(212) # 在图表2中创建子图2
x = np.linspace(0, 3, 100)
for i in range(5):
	plt.figure(1) # 选择图表1
	plt.plot(x, np.exp(i*x/3))
	plt.sca(ax1) # 选择图表2的子图1
	plt.plot(x, np.sin(i*x))
	plt.sca(ax2) # 选择图表2的子图2
	plt.plot(x, np.cos(i*x))
plt.show()

#%%

"""
绘图函数——对数坐标图:
    1.前面介绍过如何使用plot()绘制曲线图,所绘制图表的X-Y轴坐标都是算术坐标。
    下面看看如何在对数坐标系中绘图。
    2.绘制对数坐标图的函数有三个:semilogx()、semilogy()和loglog(),
    它们分别绘制X轴为对数坐标、Y轴为对数坐标以及两个轴都为对数坐标时的图表。
    3.下面的程序使用4种不同的坐标系绘制低通滤波器的频率响应曲线。 
    其中,左上图为plot()绘制的算术坐标系,
    右上图为semilogx()绘制的X轴对数坐标系,
    左下图 为semilogy()绘制的Y轴对数坐标系,
    右下图为loglog()绘制的双对数坐标系。
    使用双对数坐标系表示的频率响应曲线通常被称为波特图。(matplotlib_log.py)
"""
import numpy as np
import matplotlib.pyplot as plt
w = np.linspace(0.1, 1000, 1000)
p = np.abs(1/(1+0.1j*w)) # 计算低通滤波器的频率响应
plt.subplot(221)
plt.plot(w, p, linewidth=2)
plt.ylim(0,1.5)
plt.subplot(222)
plt.semilogx(w, p, linewidth=2)
plt.ylim(0,1.5)
plt.subplot(223)
plt.semilogy(w, p, linewidth=2)
plt.ylim(0,1.5)
plt.subplot(224)
plt.loglog(w, p, linewidth=2)
plt.ylim(0,1.5)
plt.show()

#%%

"""
绘图函数——柱状图
"""
import matplotlib.pyplot as plt 
plt.bar([1,3,5,7,9],[5,2,7,8,2], label="Example one") 
plt.bar([2,4,6,8,10],[8,6,2,5,6], label="Example two", color='g') 
plt.legend() 
plt.xlabel('bar number') 
plt.ylabel('bar height') 
plt.title('Epic Graph\nAnother Line! Whoa') 
plt.show()

#%%

"""
绘图函数——直方图:
    直方图非常像条形图,倾向于通过将区段组合在一起来显示分布
    plt.hist(src, bins,~~) 网上有很多
"""
import matplotlib.pyplot as plt 
population_ages = [22,55,62,45,21,22,34,42,42,4,99,102,110,120,121,122,130,111,115,112,80,75,65,54,44,43,42,48] 
plt.xlabel('x') 
bins = [0,10,20,30,40,50,60,70,80,90,100,110,120,130] 
plt.hist(population_ages, bins, histtype='bar', rwidth=0.8) 
plt.ylabel('y') 
plt.title('Interesting Graph\nCheck it out') 
plt.legend() 
plt.show()

#%%

"""
绘图函数——散列图:
    1.scatter()的前两个参数是数组,分别指定每个点的X轴和Y轴的坐标。
    2.s参数指定点的大 小,值和点的面积成正比。它可以是一个数,
    指定所有点的大小;也可以是数组,分别对每个点指定大小。
    3.c参数:指定每个点的颜色,可以是数值或数组。
    通过颜色映射表,每个数值都会与一个颜色相对应。
    默认的颜色映射表中蓝色与最小值对应,红色与最大值对应。
    当c参数是形状为(N,3)或(N,4)的二维数组时,则直接表示每个点的RGB颜色。
    4.marker参数:设置点的形状,可以是个表示形状的字符串,
	也可以是表示多边形的两个元素的元组,
	第一个元素表示多边形的边数,
	第二个元素表示多边形的样式,
    取值范围为0、1、2、3。0表示多边形,1表示星形,2表示放射形,
    3表示忽略边数而显示为圆形。
    5.alpha参数:设置点的透明度,
    6.lw参数:设置线宽,lw是line width的缩写。 
    7.facecolors参数:为“none”时,表示散列点没有填充色。

"""
import numpy as np
import matplotlib.pyplot as plt
plt.figure(figsize=(8,4))
x = np.random.random(100)
y = np.random.random(100)
plt.scatter(x, y, s=x*400, c=-y+300, marker=(10, 2), alpha=0.8, lw=2, facecolors="none")
plt.xlim(0,1)
plt.ylim(0,1)
plt.savefig("star")
plt.show()


#%%

"""
绘图函数——图像:
    imread()和imshow()提供了简单的图像载入和显示功能.
    img = plt.imread(“lena.jpg“)
    imread()可以从图像文件读入数据,得到一个表示图像的NumPy数组。
    它的第一个参数是文件名或文件对象,
    format参数指定图像类型,如果省略,就由文件的扩展名决定图像类型。 
    对于灰度图像,它返回一个形状为(M,N)的数组;
    对于彩色图像,返冋形状为(M,N,C)的数组。 
	其中,M为图像的高度,N为图像的宽度,C为3或4,表示图像的通道数。
	imshow()可以用来显示imread()返回的数组。如果数组是表示多通道图像的三维数组,
	那么每个像素的颜色由各个通道的值决定:
        plt.imshow(img)  #注意图像是上下颠倒的
"""
img = plt.imread("star.png")
print(img.shape)
plt.imshow(img) # 果然是上下颠倒的


#%%

"""
绘图函数——显示热图:
https://blog.csdn.net/goldxwang/article/details/76855200
    1.imshow()可以显示任意的二维数据,
    例如下面的程序使用图像直观地显示了二元函数       
    2.首先通过数组的广播功能计算出表示函数值的二维数组Z,
    注意它的第0轴表示Y轴、 第1轴表示X轴。
    然后将X、Y轴的取值范围保存到extent列表中。    
    3.将extent列表传递给 imshow()的extent参数,这样一来,
    图表的X、Y轴的刻度标签将使用extent列表所指定的范围.
"""
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cm as cm
y, x = np.ogrid[-2:2:200j, -2:2:200j]
z = x * np.exp( - x**2 - y**2)
extent = [np.min(x), np.max(x), np.min(y), np.max(y)]
plt.figure(figsize=(10,3))
plt.subplot(121)
plt.imshow(z, extent=extent, origin="lower") 
plt.colorbar()
plt.subplot(122)
plt.imshow(z, extent=extent, cmap=cm.gray, origin="lower")
plt.colorbar()
plt.show()

#%%

"""
imshow(X, cmap=None, norm=None, aspect=None, interpolation=None, 
alpha=None, vmin=None, vmax=None, origin=None, extent=None, 
shape=None, filternorm=1, filterrad=4.0, imlim=None, resample=None, 
url=None, hold=None, data=None, **kwargs)
X变量存储图像,可以是浮点型数组、unit8数组以及PIL图像,如果其为数组,则需满足一下形状   (1) M*N      此时数组必须为浮点型,其中值为该坐标的灰度    (2) M*N*3  RGB(浮点型或者unit8类型)    (3) M*N*4  RGBA(浮点型或者unit8类型)
Colormap:参数cmap用于设置热图的Colormap
Interpolation:插值计算方式:None, 'none', 'nearest', 'bilinear', 'bicubic', 'spline16', 'spline36', 'hanning', 'hamming', 'hermite', 'kaiser', 'quadric', 'catrom', 'gaussian', 'bessel', 'mitchell', 'sinc', 'lanczos'
"""
from matplotlib import pyplot as plt  
X = [[1,2],[3,4],[5,6],[1,2]]  
plt.imshow(X)  
plt.colorbar()
plt.show() 

#%%

"""
绘图函数——ogrid函数:
    ogrid函数作为产生numpy数组与numpy的arange函数功能有点类似,不同的是:
1、arange函数产生的是一维数组,而ogrid函数产生的是二维数组
2、arange函数产生的是一个数组,而ogrid函数产生的是二个数组
3、ogrid函数产生的数组,第一个数组是以纵向产生的,即数组第二维的大小始终为1。第二个数组是以横向产生的,即数组第一维的大小始终为1。
"""
x,y = np.ogrid[0:10:1,0:10:2] # 整数步长
print(x)
print(y)
# 复数步长的设置是通过j进行设置的,如5j。复数前表示的是,用几个数值来等分整个区间。
x,y = np.ogrid[0:10:6j,0:10:4j]
print(x)
print(y)

#%%

"""
绘图函数——三维绘图:
mpl_toolkits.mplot3d模块在matplotlib基础上提供了三维绘图的功能。由于它使用matplotlib的二维绘图功能来实现三维图形的绘制工作,因此绘图速度有限,不适合用于大规模数据的三维绘图。如果需要更复杂的三维数据可视化功能,可使用Mayavi。(matplotlib_surface.py 使用matplotlib绘制三维曲面)
mplot3d 模块下主要包含 4 个大类:
•mpl_toolkits.mplot3d.axes3d():包含了各种实现绘图的类和方法,最常用
•mpl_toolkits.mplot3d.axis3d():包含了和坐标轴相关的类和方法
•mpl_toolkits.mplot3d.art3d():一些可将 2D 图像转换并用于 3D 绘制的类和方法
•mpl_toolkits.mplot3d.proj3d():包含一些零碎的类和方法,例如计算三维向量长度等
"""

#%%

# 三维线形图
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import numpy as np
# 生成数据
x = np.linspace(-6 * np.pi, 6 * np.pi, 1000)
y = np.sin(x)
z = np.cos(x)
# 创建 3D 图形对象
fig = plt.figure()
ax = Axes3D(fig)
# 绘制线型图
ax.plot(x, y, z)
# 显示图
plt.show()


#%%

# 3D曲线
import matplotlib as mpl
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
import matplotlib.pyplot as plt 
fig = plt.figure()
ax=Axes3D(fig)
theta = np.linspace(-4 * np.pi, 4 * np.pi, 100)
z = np.linspace(-2, 2, 100)
r = z**2 + 1
x = r * np.sin(theta)
y = r * np.cos(theta)
ax.plot(x, y, z, label='parametric curve')
ax.legend() 
plt.show()


#%%

# 3D网状线
from mpl_toolkits.mplot3d import axes3d
import matplotlib.pyplot as plt  
fig = plt.figure()
ax=Axes3D(fig)
# Grab some test data.
X, Y, Z = axes3d.get_test_data(0.05) # Plot a basic wireframe.
ax.plot_wireframe(X, Y, Z, rstride=10, cstride=10) 
plt.show()


#%%

# 三维散点图
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import numpy as np
# x, y, z 均为 0 到 1 之间的 100 个随机数
x = np.random.normal(0, 1, 100)
y = np.random.normal(0, 1, 100)
z = np.random.normal(0, 1, 100)
fig = plt.figure()
ax = Axes3D(fig)
ax.scatter(x, y, z)
plt.show()


#%%

from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import numpy as np
def randrange(n, vmin, vmax):#在vmin和vmax间产生n个随机数
    return (vmax - vmin) * np.random.rand(n) + vmin
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d') #可替换为ax = Axes3D(fig)
n = 100
# For each set of style and range settings, plot n random points in the box
# defined by x in [23, 32], y in [0, 100], z in [zlow, zhigh].
for c, m, zlow, zhigh in [('r', 'o', -50, -25), ('b', '^', -30, -5)]:
    xs = randrange(n, 23, 32)
    ys = randrange(n, 0, 100)
    zs = randrange(n, zlow, zhigh)
    ax.scatter(xs, ys, zs, c=c, marker=m)
ax.set_xlabel('X Label')
ax.set_ylabel('Y Label')
ax.set_zlabel('Z Label')
plt.show()



#%%

# 3D曲面
import numpy as np
import mpl_toolkits.mplot3d 
import matplotlib.pyplot as plt
x, y = np.mgrid[-2:2:20j, -2:2:20j] 
"""
res = np.mgrid[-3:3:.1,-3:3:.1]
生成从-3到3的二维坐标
第一部分是y轴的范围
第二部分是x轴的范围
返回数组的res[0]是y轴,res[1]是x轴
"""
z = x * np.exp( - x**2 - y**2)
fig=plt.figure()
ax = plt.subplot(111, projection='3d') 
#ax=Axes3D(fig)
ax.plot_surface(x, y, z, rstride=2, cstride=1, cmap = plt.cm.Blues_r) 
ax.set_xlabel("X")
ax.set_ylabel("Y")
ax.set_zlabel("Z")
plt.show()


#%%

"""
绘图函数——投影简介:
投影模式决定了点从数据坐标转换为屏幕坐标的方式.可以通过下面的语句获得当前有效的投影模式的名称:
from matplotlib import projections
projections.get_projection_names()
['3d', 'aitoff', 'hammer', 'lambert', 'mollweide1, 'polar', 'rectilinear']
只有在载入mplot3d模块之后,此列表中才会出現’3d’投影模式. 
’aitoff’、’hammer’, ’lamberf’,’mollweide’等均为地图投影,
’polar’ 为极坐标投影,
'rectilinear’則是默认的直线投影模式.
4调用Axes3D对象的plot_surface()绘制三维曲面。其中:
参数x、y、z都是形状为(20,20) 的二维数组,数组x和y构成了 X-Y平面上的网格,而数组z则是网格上各点在曲面上的取值。 
通过cmap参数来指定值和颜色之间的映射,即曲面上各点的高度值与其颜色的对应关系。	
rstride 和cstride参数分别是数组的第0轴和第1轴的下标间隔.对于很大的数组,使用较大的间隔可以提高曲面的绘制速度。程序中,plot_surfece()调用和下面的语句是等价的:
ax.plot_surface(x[::2,:], y[::2,:], z[::2,:], rstride=1, cstride=1)
"""
from mpl_toolkits.mplot3d import Axes3D

fig = plt.figure()
ax = Axes3D(fig)
X = np.arange(-4, 4, 0.25)
Y = np.arange(-4, 4, 0.25)
X, Y = np.meshgrid(X, Y)
R = np.sqrt(X**2 + Y**2)
Z = np.sin(R)

ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap='hot')
plt.show()
发布了36 篇原创文章 · 获赞 20 · 访问量 2996

猜你喜欢

转载自blog.csdn.net/weixin_43360801/article/details/103318134