
主要任务:初步介绍matplotlib模块下的子模块pyplot的使用,pyplot是一个2-D绘图库,主要用于绘制一元函数图像(若绘制二元函数应使用3-D绘图库)。pyplot提供了一套类似于MATLAB的命令风格的函数式绘图工具(同时也提供了面向对象的绘图工具),和Matlab一样,pyplot中有当前图像(figure)和当前轴域(axes)的概念,所有的作图命令都是对当前的对象作用。可以通过gca()获得当前的axes,通过gcf()获得当前的figure,每个绘图函数都会对图像做出特定的改变,譬如:创建一个图像(figure)、在一个图像中创建一个绘图区域(plotting area)、在一个绘图区域中绘制线条(line)、使用标签装饰制图(plot)等。
应着重理解figure、subplot、axes三个对象:
figure是最大的单位或者说范畴,其中可以包含多个子图(subplot/axes),可以认为subplot和axes是同一概念,都是指子图对象,在翻译时称axes为“轴域”,即整个坐标系区域。它们的区别似乎主要在于:subplot用于创建规则的行列子图矩阵,而axes可以在任意指定位置创建子图,更具灵活性,subplot创建的子图是不可重叠的,而axes可以,即axes可以用来创建内嵌子图。
其他概念(concept):
在最简单的绘图工作中,我们使用plot()创建一个绘图区域(plotting area),然后我们在这个区域中绘制线条、散点、柱状图等,实际上这个绘图区域就相当于是一个一行一列编号为1的子图对象(subplot(111))。当你要指代一个只具有一个直角坐标系的子图对象的时候,为了区别于之前的图像(figure)概念,我们使用plot(制图)来标识,在接下来的文档说明中,我不会再使用中文,因为实在难以区分。因此subplot、plot、axes其实都是一回事,都是一个可以用于绘图的最小plotting area。
import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import colors as mcolors
plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus']=False
import scipy.stats
from PIL import Image
# 绘制函数图像:y=2x+3
# x区间:[-5,5]
x=np.linspace(-5,5,2) # 由于绘制的是直线,而两点确定一条直线,所以只要两个端点即可
# The coordinates of the points or line nodes are given by x, y.
plt.plot(x,2*x+3) # 此处plot()接受两个参数,分别表示x轴坐标(自变量)和对应的y轴坐标(因变量)
说实话,对这张图,我特别不满意,它经过哪些点?两个端点的刻度没有显示出来?刻度怎么调整,乍一看,我还以为是y=0.5x呢!最重要的是仅仅从这张图,我完全没有办法恢复出函数原型,缺少必要的图像说明啊!但是也不用担心,这些问题以后会得到解决。
# 两点确定一条直线(y=2x+3):
plt.plot([3,5]) # 找两个点:当x=0和x=1时(只能找这两个点),y分别为3和5
此处的函数调用可能令人疑惑不解,为什么x-axis的取值为0-1而y-axis的取值为3-5?因为当你只提供一个(一维)列表或数组的时候(记作a),plot()命令将视其为y(因变量)的一系列取值,而相应的x(自变量)将为:range(0,len(a)),即plot(a)自动转换为plot(range(0,len(a)),a)
函数原型:matplotlib.pyplot.plot(*args, scalex=True, scaley=True, data=None, **kwargs)
调用签名(Call signatures 这什么意思?):plot([x], y, [fmt], data=None, **kwargs)或者plot([x1], y1, [fmt1], [x2], y2, [fmt2], ..., **kwargs),其中[]表示可选参数
返回值:A list of Line2D objects
注:matplotlib出图的过程和我们画图过程差不多,先生成 X 的一个取值数组,如要画区间[0,1]的图像,则先取[0,1]之内的一组数组(如:x=arange(0,1,0.01)表示 x 以 0.01 为步长取 100 个点),然后取对应 x 的 y 的值的一组数据,这样以坐标(x,y)画出的图就是一条曲线了,点和点之间以直线相连,因此曲线的光滑程度完全取决于点的细密程度
Format Strings:
fmt用于定义几种特定的线条对象(Line2D)的外观(appearance)属性:颜色、标记和线条样式,在不对外观进行任何设置的情况下,线条默认为“无点标记的蓝色实线”;fmt是一个快捷的格式化字符串(定义:fmt = '[color][marker][line]',color、marker和line都是任意可缺省的,默认选项分别为:'b'、''、'-',表示“蓝色”、“无标记”、“实线”,如果三者同时缺省,那还不如不设置fmt参数;注意:当fmt只设置颜色属性时,可以使用任何matplotlib.colors规范,例如颜色全名(绿色:"green")或颜色的十六进制字符串代码(绿色:"008000");特别注意:当提供了marker参数时,其认为我们的本意是绘制散点图,因此此时line='',除此以外当line缺省时,都是默认line='-'</font>),每个字符表示一种特征,这个字符串可以是特征的任意组合;fmt的功能完全可以通过给定键值对形式的Line2D对象属性作为函数参数来实现,且后者提供了完备的外观设定(譬如线条宽度、标记大小等),fmt仅仅具有某些常见外观设置上的方便性;当fmt和Line2D的关键字属性产生冲突时,后者优先。
x,y=[1,2,3,4,5],[1,4,9,16,25]
plt.plot(x,y,'bo')
plt.plot(y,'r+') # 在当前plotting area上继续绘制并显示修改(只在交互模式起效)
plt.plot(x,y,'bo',y,'r+') # 同时具现化两种函数关系
plt.plot(x,y,color='red',marker='+',linestyle='') # 等同于plot(x,y,'r+'),可见fmt格式字符串的方便性
plt.plot(x,y,'green') # fmt格式字符串在用于单独设置颜色属性时,可以指定颜色全名或其十六进制代码
Plotting labelled data:
plot()提供了一种通过标记数据创建plot的方式,所谓标记数据,指的是可以通过data['label']标签索引来获取所需数据的方式,显然,字典对象就符合条件。从之前的实验可知:plot()参数接受两个参数,自变量x和因变量y(它们都是一维序列),因此,我们应当能够从标记数据中根据指定的标签获取所需的自变量和因变量数据。字典对象应该是这样的:dict={'xlabel':[...],'ylabel':[...],...},于是有:x=dict['xlabel'],y=dict['ylabel'],但我们无需通过plot(dict['xlabel'],dict['ylabel'])的方式调用,而是:plot('xlabel','ylabel',data=dict)
注:符合条件的标记数据可以是字典对象、pandas.DataFame或numpy的结构化数组(All indexable objects are supported. This could e.g. be a dict, a pandas.DataFame or a structured numpy array.)
# 从字典对象创建plot
dicts={'x-axis':[1,2,3,4,5],'y-axis':[1,4,9,16,25]}
plt.plot('x-axis','y-axis',data=dicts,marker='^',linestyle='')
# 从numpy结构化数组创建plot,通过字段名获取的数据应为一维
# 现有一个结构化数组,其中存储了不同班级的学生的身高、体重信息,数组的形状无关紧要,因为“记录”的数据结构中的信息十分完备,我们不需要依靠数组的维度来区分不同的班级
# 要求根据不同的班级,绘制学生的身高-体重分布(绘制散点图一般使用scatter(),没什么区别,就是用起来简洁一点)
a=np.array([[('daiyang',165,58.5,1),('zhouqifei',170,57,1),('daixiaodong',173,59.5,1),('miaosiyu',166,53.5,1)],[('liuwenwei',167,54.6,2),('liushaoliang',175,55.5,2),('daizhongliang',178,58,2),('zhangjingjing',166,52,2)]],dtype=[('name','S20'),('height','f'),('weight','f'),('class','i4')])
print(a)
t=a[a['class']==1] # 布尔索引:和数组掩码相与返回的结果是一个一维数组,其中是符合条件的元素
print(t)
plt.plot('height','weight',data=t,marker='^',linestyle='',label='class 1')
plt.plot('height','weight',data=a[a['class']==2],marker='o',linestyle='',label='class 2')
plt.legend()
plt.xlabel('Height(cm)')
plt.ylabel('Weight(kg)')
Plotting multiple sets of data:
在同一plotting area绘制多次数据集,有多种实现方式:
1) 最直接的方式就是多次调用plot()(仅限于交互模式)
2) 如果已有的数据是一个二维数组,那么可以将某一列指为x,其余列指为y(此前,我们的plot()接受两个参数,一个是x,一个是y,分别表示点在x轴上和y轴上的坐标,x与y都是一维的等长的序列,而此处很显然,y是一个二维的数组了,这是最显著的区别,但是须保证:x(一维)的长度与y(二维)的0轴长度一致),若“其余列”共有n列,那么相当于法1)执行n次plot():plot(x,y[:,0])、plot(x,y[:,1])、plot(x,y[:,2])、...plot(x,y[:,n-1]),即根据x和y的每一列分别逐一地绘制相应的线条
3) 指定多组 [x],y,[fmt] 的组合,plot函数将会为每一数据集(x和y)分别进行绘制,[]表示可选,前面我们已经举过示例,譬如:plot(x1,y1,'red',x2,y2,'pink'),但应当注意的是,当存在多个组合时,fmt不能随意省略,fmt可以充当不同组合的分隔标识,这种分隔标识将为系统所理解,虽然文档没有提及,但这确是为实践所检验的真理。在此情况下,任何其他关键字参数都适用于所有数据集
data=np.arange(12).reshape(4,3)
print(data)
plt.plot(data[0],data[1:],marker='*',linestyle='') # 以某一行作为x,其余行作为y,这种方式不推荐,虽然可行,但是由于绘制的行为总是:
# 取x(一维)和y(二维)的每一列作为一配对进行一次绘制,x的长度必须与y的0轴长一致,所以要满足这一点,则data只能为m*(m-1)型二维数组,譬如4*3、7*6等
print(data[[0,1,3]])
plt.plot(data[2],data[[0,1,3]],marker='*',linestyle='') # 将第3行作为x,将其余行作为y
plt.plot(data[:,0],data[:,1:],marker='*',linestyle='') # 将第0列作为x,将其余列作为y
# 实际上,对于plt.plot(x,y)来说,x、y都可以是二维数组,但行数需一致,若列数不同,首先对x或y进行扩展,使得两个数组形状完全一致。假设x有m列,y有
# n列,m<n,且n-m=r,则对x进行扩展,将x的第0列到第r-1列(前r列)沿1轴添加到x上,使成为n列数组,x、y形状一致。于是plot()可以绘制n条线,分别取x和y的
# 第1列绘制第一条线,再取x和y的第2列绘制第二条线...
plt.plot(data,data[:,1:],marker='.')
print(data) # 参数x
print(np.hstack((data[:,1:],data[:,0:1]))) # 参数y扩展后,与参数x形状相同
d=np.arange(28).reshape(4,7)
print(d)
plt.plot(d[:,0],d[:,1:],marker='*',linestyle='')
x=range(5)
y=np.arange(15).reshape(3,5)
print(y)
plt.plot(x,y[0],y[1],'r^',x,y[2],linestyle='',marker='+') # marker关键字参数设置适用于全部三条线,且关键字参数优先于fmt设置
函数原型:matplotlib.pyplot.subplot(*args, **kwargs)
Call signatures:subplot(nrows, ncols, index, **kwargs)subplot(pos, **kwargs)subplot(ax)
args参数:一个3位整数或三个独立的整数(只有当三个整数都小于等于9才能写成一个三位整数),用于描述子图在子图矩阵中的位置。三个整数按顺序为nrows,ncols和index,分别表示行、列、索引。nrows和ncols将构成一个既定的子图矩阵,其中每一个子图都拥有一个唯一的索引编号,其是C风格的索引,根据索引我们可以指定子图矩阵中的任意子图对象。
projection参数:{None, 'aitoff', 'hammer', 'lambert', 'mollweide', 'polar', 'rectilinear', str}, optional
设置子图的“投影类型”,其中我最熟悉的就是'polar'极坐标系(也可用polar()绘制极坐标系)。默认情况下,projection='rectilinear'
polar参数:True or False,当其为True时,等同于projection='polar'
sharex,sharey参数:Axes, optional
参数接受一个axes对象(记作a),即一个画板,使当前axes与a共享x-axis或y-axis(The axis will have the same limits, ticks, and scale as the axis of the shared axes.)
kwargs关键字参数设置其他axes属性,当投影非默认时,即采用其他投影则可能还有其他关键字参数,属性参见
label参数:具体使用?
subplot()是对Figure.add_subplot的包装,但是有一些行为上的细微的差别:见文档 Note 部分
靠,没整明白啊
须知,plot()是用笔绘制图形,而figure()或subplot()是在准备画板等初步工作,此前(我们的实验)虽然没有写过figure()或者subplot(),但是它们都是被默认执行了的,又当我们添加语句figure()或subplot(),其实际上是为:figure(1)、subplot(111)
当我准备好第一块子画板,并进行某些线条绘制后,来到第二块子画板,突然发现,第一块有所欠缺,想做修改,但是系统当前axes对象已经切换到了第二块子画板,怎么回去到上一块子画板呢?Matplot命令我还真不知道怎么“切换”,我是利用面向对象的方法,每次执行subplot()时将返回值保存下来即可获取当时创建的axes对象,也就是那块子画板,然后直接用面向对象绘制线条等,如果仍想使用命令风格,则可利用sca()将某一子画板设置为“系统当前axes”(set current axes)
如果创建了多个figure对象:plt.figure(1)plt.figure(2)... 对figure的切换,仍然调用plt.figure(编号)即可切换至指定编号的figure
plt.subplot(221) # 一个2*2的子图矩阵,准备索引1、3和4的子图用于绘图
plt.subplot(2,2,4,projection='polar',facecolor='yellow') # 224
plt.subplot(223,projection='aitoff')
# 获取当前figure,进行配置,也可以在创建figure的时候配置:plt.figure(facecolor='red')
fig=plt.gcf()
fig.set_facecolor('pink')
plt.suptitle('a figure of three subplots')
# 获取当前axes,进行相应配置,也可以在创建axes的时候配置:见第二行
ax=plt.gca()
ax.set_facecolor('gray')
axes=[i for i in range(4)]
for i,c in enumerate('rgby'):
axes[i]=plt.subplot(221+i,facecolor=c)
plt.plot([0,0.8],[1,0.25],color='white') # 系统维持的当前axes为第四个子画板
axes[0].plot([0,0.8],[0.25,1],color='white')
plt.axhline(0.5,color='black') # 当前axes仍是第四块子画板,画水平线
plt.sca(axes[1]) # 设置第二块子画板为“当前axes”
plt.axvline(0.4,color='red') # 当前axes为第二块子画板,画垂线
ax1=plt.subplot(2,2,1)
plt.axis([0,8,0,1]) # 就是:ax1.axis(...)
# add a subplot with no frame
ax2=plt.subplot(222,frameon=False)
plt.xticks([1,3,5,7,9])
ax2.annotate('frameon=False',(0.5,0.5),fontsize=15)
# add a subplot that shares the x-axis with ax1
plt.subplot(224,sharex=ax1)
# add a subplot that shares the x-axis with ax2
plt.subplot(223,sharex=ax2)
# plot()之后,再使用subplot()首先会删除原先存在的将导致发生重叠的画板
plt.plot([1,2,3]) # 相当于subplot(111)
plt.subplot(212,title='Axes 2') # 或者plt.subplot(211),结果都是一样的,原来的画板被删除了,前后两个子图矩阵发生重叠,删去前者
# 要想改变此行为,应改而使用add_subplot()或者axes()配置子画板
函数原型:matplotlib.pyplot.tight_layout(pad=1.08, h_pad=None, w_pad=None, rect=None)
参数说明:
pad参数会设置h_pad=w_pad的值,其中h_pad表示上一行子图与其下一行子图的间距,w_pad设置左列子图与其右列子图的间距,默认情况下,h_pad和w_pad与pad是一样的,当然我们可以单独设置。rect是一个四元组:(left, bottom, right, top),默认为(0,0,1,1),其构成一个长方形区域,然后子图矩阵将试着去适应它(充满它),通过调整子图的大小。
for i in range(4):
plt.subplot(221+i,title='Axes'+str(i+1))
plt.annotate('Too crowded!',(0.05,0.75),fontsize=20,color='r')
for i in range(4):
plt.subplot(221+i,title='Axes'+str(i+1))
plt.tight_layout(rect=(0,0,2,2))
for i in range(4):
plt.subplot(221+i,title='Axes'+str(i+1))
plt.tight_layout(pad=2) # 默认pad=1,所以一般不加参数就可以得到满意的结果
for i in range(4):
plt.subplot(221+i,title='Axes'+str(i+1))
plt.tight_layout(h_pad=5,w_pad=0) # 试着将w_pad取负
函数原型:matplotlib.pyplot.subplots_adjust(left=None, bottom=None, right=None, top=None, wspace=None, hspace=None)
参数说明以及推荐的取值:left = 0.125 # the left side of the subplots of the figureright = 0.9 # the right side of the subplots of the figurebottom = 0.1 # the bottom of the subplots of the figuretop = 0.9 # the top of the subplots of the figurewspace = 0.2 # the amount of width reserved for space between subplots, expressed as a fraction of the average axis widthhspace = 0.2 # the amount of height reserved for space between subplots, expressed as a fraction of the average axis height
我曾试着同时使用tight_layout()和subplots_adjust()来解决一些布局问题,参见"patches与path.ipynb"#Path心形绘制
for i in range(4):
plt.subplot(221+i)
plt.subplots_adjust(bottom=0.9,top=1)
函数原型:matplotlib.pyplot.subplots(nrows=1, ncols=1, sharex=False, sharey=False, squeeze=True, subplot_kw=None, gridspec_kw=None, **fig_kw)
参数说明:
nrows, ncols参数设置子图矩阵的行列数。
sharex, sharey参数:bool or {'none', 'all', 'row', 'col'}, default: False
这两个参数用于控制同一列或同一行的子图对x轴或y轴的共享行为(见下例)。一般我就取布尔值。当子图具有沿列的共享x轴时,仅创建或配置最底部一行子图的x刻度标签。类似地,当子图具有沿行的共享y轴时,仅创建或配置第一列子图的y刻度标签。若稍后要打开其他子图的轴刻度,应使用tick_params
fig,ax=plt.subplots(2,1,sharex=True) # 子图矩阵的每一列共享x轴,“当前axes”为最后一个子图对象
plt.annotate('the two subplots along one column\n share the same x-axis',(0.4,0.5),fontsize=15)
print(type(ax),ax.shape) # 虽然我们创建的子图矩阵是(2,1)形状,但是返回的是一个一维数组对象(当子图矩阵只有一行或者一列的时候才会如此),其中是创建的全部的axes子图对象
fig,ax=plt.subplots(2,1,sharey=True) # 子图矩阵的每一行共享y轴
print(ax.shape)
fig,ax=plt.subplots(2,2,sharey=True) # 同上
print(ax.shape)
plt.annotate('the two subplots along one row share the same y-axis',(0.1,0.5)) #“当前axes”为最后一个子图对象
ax[0,0].annotate('the two subplots along one row share the same y-axis',(0.7,0.5))
ax[0,1].annotate('How to solve it?(the Hidden)',(0.2,0.25),fontsize=20,color='r')
ax[0,0].set_facecolor('r')
ax[0,1].set_alpha=0.1 # 为撒不起效呢?
#dir(ax[0,1]) # 命令不行就面向对象,找属性方法
# 绘制多个子图矩阵、调整间距(注意,subplot()只能在一张figure中创建一个子图矩阵,subplots()同样如此,你应该发现了,subplots()返回值一个是figure对象,另一个是子图多维矩阵,即每个子图矩阵仍占有一整个figure,亦即一个figure只能有一个子图矩阵或网格子图(subplot2grid))
plt.subplots(1,2) # 子图矩阵1,同样对subplot()也可如此
plt.subplots(2,1) # 创建了第二个子图矩阵
函数原型:matplotlib.pyplot.subplot2grid(shape, loc, rowspan=1, colspan=1, fig=None, **kwargs) 参数说明:
shape参数:二元整数序列[m,n],将figure划分成m行n列的网格
loc参数:sequence of 2 ints,设置轴域axes(子图)在网格中的位置
rowspan参数设置子图向下跨越的网格行数,默认为1
colspan参数设置子图向右跨越的网格列数,默认为1
fig参数指定子图所在的figure,默认就是“当前figure”
kwargs关键字参数设置其他将传递给add_subplot()的选项
# 欲将figure分解为如下网格(3*3形状),每个格子为一个子图(axes)
plt.axis([0,3,0,3]) # axis()和xticks()、yticks()缺一不可!
plt.xticks([0,1,2,3])
plt.yticks([0,1,2,3])
plt.axhline(2)
plt.plot([0,2],[1,1])
plt.plot([2,2],[0,2])
plt.plot([1,1],[0,1])
# 网格子图无索引编号,此处仅仅作为区分或称呼
plt.annotate('Axes1',(1,2.5),color='r')
plt.annotate('Axes2',(1,1.5),color='r')
plt.annotate('Axes3',(2.5,1),color='r')
plt.annotate('Axes4',(0.5,0.5),color='r')
plt.annotate('Axes5',(1.5,0.5),color='r')
plt.annotate('(0,0)',(0,3))
plt.annotate('(1,0)',(0,2))
plt.annotate('(2,0)',(0,1))
plt.annotate('(2,1)',(1,1))
plt.annotate('(1,2)',(2,2))
plt.subplot2grid([3,3],loc=[0,0],colspan=3)
plt.subplot2grid([3,3],loc=[1,0],colspan=2)
plt.subplot2grid([3,3],loc=[1,2],rowspan=2)
plt.subplot2grid([3,3],loc=[2,0])
plt.subplot2grid([3,3],loc=[2,1])
plt.tight_layout()
函数原型:matplotlib.pyplot.axes(arg=None, **kwargs)
Call signatures:plt.axes()plt.axes(rect, projection=None, polar=False, **kwargs)plt.axes(ax)
参数说明:
arg参数:{ None, 4-tuple, Axes },此函数的行为根据arg参数取值类型的不同而不同:
subplot(111, **kwargs)plt.sca(),即将arg参数所指axes设置为“当前axes”,同时隐含地改变axes的“父亲”,使“当前figure”对象为arg参数所指axes所在figure(此方法似乎不被推荐)projection参数:{None, 'aitoff', 'hammer', 'lambert', 'mollweide', 'polar', 'rectilinear', str}, optional
polar参数,布尔值,为True等同于“投影”设为'polar'
sharex,sharey参数:Axes, optional,共享某axes的相同的x轴和y轴
label参数:为所创建的axes设置标签
kwargs关键字参数设置axes轴域的属性,当非默认投影时,可能还有其他关键字参数
文档注解Note不明白
plt.plot([1,2,3,4],color='black') # 这玩意儿画在subplot(111)上
plt.axes([.2,.6,.2,.2],facecolor='green') # 与上面的subplot在同一figure上
plt.plot([4,3,2,1],color='red')
plt.figure(figsize=(10,10))
plt.axes([0,0,.4,.4])
plt.axes([.2,.2,.4,.4])
函数原型:matplotlib.pyplot.grid(b=None, which='major', axis='both', **kwargs)
参数说明:
b:用于控制网格线的显示。b取True,表示显示网格,取False表示不显示网格,但是如果提供了任何kwargs关键字参数,则认为用户本意是希望显示网格线的,b参数失效。默认值None具有特殊效用:当参数b为None且未提供任何关键字参数时,grid(...)成为一个依据当前网格线状态执行打开或关闭网格线动作的"ON/OFF"开关,因此当我们仅仅想要显示原始的网格线而不做任何配置的时候,只需执行:plt.grid(),可代替:plt.grid(b=True)
which:{'major', 'minor', 'both'},指定要应用更改的是主刻度还是次刻度上的网格线,默认更改应用在主刻度上的网格线,当指定which为'both'或'minor'时要显示出效果,首先要打开次刻度上的网格线显示开关(minorticks_on())
axis:{'both', 'x', 'y'},指定要应用更改的是x轴还是y轴上的网格线
kwargs:kwargs关键字参数用于设置网格线的外观,其为Line2D对象属性。
plt.minorticks_on():
在轴上显示小刻度(感觉比“次刻度”顺耳啊),但须知:显示小刻度可能会降低性能,如果绘图速度有问题,可以使用minor ticks_off()将其关闭
# b参数
plt.plot()
plt.grid(True,c='red') # 打开,等同于plt.grid(c='red')
plt.grid() # 开关,刚才是打开状态,因此现在为关闭
plt.grid(b=None,axis='y') # 开关,刚才处于关闭状态,于是打开,等同于plt.grid(axis='y'),表示“显示”将只应用在y轴上的网格线
# axis参数
plt.plot()
plt.grid(axis='y',c='blue',linestyle=':') # 更改应用在y轴上的网格线,颜色为蓝色,线条格式为‘某种’虚线
plt.grid(axis='x',c='green',linestyle='--') # 类同上
# which参数
plt.plot()
plt.minorticks_on() # 打开次刻度上的网格线显示开关
plt.grid(which='both',c='blue',linestyle=':') # 将更改应用到全部x轴和y轴的主刻度和次刻度上去,蓝色
plt.grid(axis='x',c='green',linestyle='--') # 将更改应用到x轴上的主刻度(默认)上的网格线,绿色
x=np.arange(0,10,0.01)
plt.plot(x,np.power(x,0.5))
plt.plot([1],[1],marker='o') # 突出某一个点
plt.minorticks_on()
plt.grid(which='both') # 此时grid(...)充当“开关”,根据之前状态,现在是“开”,于是将“开”应用到“which”全部大小刻度上的网格线
plt.annotate('(1,1)',(1.2,0.95))
plt.annotate(r'$y=x^{\frac{1}{2}}$',(0.8,0.8),xycoords='figure fraction',fontsize=15) # (0.8,0.8)表示靠近右上角的位置,(0,0)表示左下角,(0.5,0.5)表示中央位置
函数原型:matplotlib.pyplot.axis(*v, **kwargs)
Call signatures:xmin, xmax, ymin, ymax = axis()xmin, xmax, ymin, ymax = axis(xmin, xmax, ymin, ymax)xmin, xmax, ymin, ymax = axis(option)xmin, xmax, ymin, ymax = axis(**kwargs)
xmin, ymin, xmax, ymax 是可选的float类型参数,用于设置坐标轴的范围或者说视区,要么不设置要么必须全部给出。
其他参数(看不懂,艹你LM)
注:一个常见的需求是,你希望图案所在的轴域的x和y轴是等宽比例显示的,你只需要执行plt.axis('equal'),如果同时设置轴域范围,则:
plt.axis('equal')
plt.axis([xmin,xmax,ymin,ymax])
注意顺序不要颠倒哦
plt.plot(range(2,9),np.linspace(10,80,7))
plt.axis([0.5,9.5,5,90]) # 实际上是[1,10,10,90],WHY?
plt.grid()
函数原型(以xlim()为例):matplotlib.pyplot.xlim(*args, **kwargs)
Call signatures:left, right = xlim() # return the current xlim,相当于对当前axes调用get_xlim()xlim((left, right)) # set the xlim to left, rightxlim(left, right) # set the xlim to left, right
可以通过关键字参数只设置某一边限:xlim(right=3) # adjust the right leaving left unchangedxlim(left=1) # adjust the left leaving right unchanged
对于ylim(),相应的关键字参数则是:top和bottom
xlim(...)设置限制将关闭x轴的自动缩放(Setting limits turns autoscaling off for the x-axis.)(什么意思)
plt.xlim(-10,7)
plt.ylim(5,13)
plt.ylim(bottom=-5)
# 朱笔画圈
plt.text(-10,11.77,' ',bbox=dict(boxstyle='circle',ec='r',fc='white',linewidth=2,fill=False)) # 还有其他好办法吗?见./patches与path.ipynb#画圆
plt.text(-10,-4.25,' ',bbox=dict(boxstyle='circle',ec='r',fc='white',linewidth=2,fill=False))
plt.text(-10,-5.25,' ',bbox=dict(boxstyle='circle',ec='r',fc='white',linewidth=2,fill=False))
plt.text(6,-5.25,' ',bbox=dict(boxstyle='circle',ec='r',fc='white',linewidth=2,fill=False)) # 好蠢啊,应该写个for循环的。。
函数原型(以xticks()为例):matplotlib.pyplot.xticks(ticks=None, labels=None, **kwargs)
Call signatures:locs, labels = xticks() # Get locations and labels,等同于在axes对象上调用 get_xticks() 和 get_xticklabels() 方法xticks(ticks, [labels], **kwargs) # Set locations and labels,等同于在axes对象上调用 set_xticks() 和 set_xticklabels() 方法
刻度标签labels参数是可选的
关键字参数kwargs用于设置标签labels(Text labels)的外观属性(Text properties can be used to control the appearance of the labels.)xticks([])禁用轴刻度及标签
x=np.arange(0,2*np.pi,0.1)
y=np.sin(x)
plt.plot(x,y)
plt.xticks(np.arange(0,4*np.pi,0.5*np.pi),[0,'π/2','π','3π/2','2π','5π/2','3π','7π/2','4π']) # labels可以长于或短于ticks,当较短时,则有些刻度无标签,当较长时,则进行截取
plt.yticks([-1,0,1,2],color='purple',fontsize='xx-large')
#plt.xticks([])
plt.grid()
# 和axis()设置刻度的区别:axis()只能设置轴最小和最大刻度,且刻度均匀,而xticks()和yticks()可以设置全部刻度,想怎么细分就怎么细分,任意设置
plt.xticks([1,2,4,7,11,16]) # 设置不均的刻度
plt.grid()
直观上,脊柱就是我们的axes的四个框框,特别是左边框和下边框都是有刻度的,也就是纯粹意义上的“直角坐标系”,平时所见手绘的直角坐标系都是位于中央,很容易设置,为了将脊柱放在图的中间,我们必须将其中的两条(上和右)设置为无色或者隐去,然后调整剩下的两条到合适的位置——至数据空间的 0 点
# 脊柱颜色
plt.figure(figsize=(3,3))
plt.subplot()
ax=plt.gca()
ax.spines['left'].set_color('blue')
ax.spines['bottom'].set_color('red')
# 脊柱宽度
ax.spines['top'].set_linewidth(5)
# 脊柱类型
ax.spines['right'].set_linestyle('--')
# 去掉脊柱
plt.figure(figsize=(3,3))
ax=plt.subplot()
ax.spines['top'].set_visible(False) # 隐去上边框
ax.spines['bottom'].set_visible(False) # 隐去下边框
ax.spines['left'].set_visible(False) # 隐去左边框
ax.spines['right'].set_visible(False) # 隐去右边框
# 移动脊柱
ax=plt.subplot()
x=np.linspace(-np.pi,np.pi,100)
y=np.sin(x)
plt.plot(x,y)
ax.spines['left'].set_position(('data',0)) # 'data'表示“数据空间”
ax.spines['bottom'].set_position(('data',0))
ax.spines['top'].set_visible(False) # 上边框隐去
ax.spines['right'].set_color(None) # 右边框无色
函数原型:matplotlib.pyplot.text(x, y, s, fontdict=None, withdash=False, **kwargs) 参数说明:
参数x,y指定文本的放置位置,实际上是指定文本左下角的位置坐标,默认其是在当前绘制的数据坐标系(data coordinates)中,也可以转换为其他坐标系,譬如可以指定文本是在“轴坐标系”(axis coords)中(通过给定关键字参数transform进行设置),x=0,y=0表示左下角,x=1,y=1表示右上角,x=0.5,y=0.5表示中心。
参数s指定要显示的说明文本
参数fontdict,一个可选的字典参数,用于覆盖默认的Text属性,fontdict默认取值为None,此时Text属性由rc参数决定(rc是什么?)
参数withdash为True时,表示创建一个TextWithDash实例而不是Text实例(What?),默认为False
kwargs关键字参数用于其他设置文本Text的选项,其为Text属性
x=np.arange(-10,10,0.1)
y=x*x
plt.plot(x,y)
plt.axis([-15,15,-5,110])
plt.grid()
plt.text(0.5,20,'y=x^2') # a simple example
plt.text(10,80,'I hate you!',fontsize=20,rotation=30)
plt.text(-10,80,'Muggledy',fontsize=25,bbox=dict(boxstyle="round",ec=(1.,0.5,0.5),fc=(1.,0.9,0.8)),rotation=10) # bbox设置注释框,ec是边框颜色,fc是内部颜色
plt.text(-5,40,'Python',bbox=dict(boxstyle='circle',facecolor='gray',alpha=0.4)) # simple
# transform参数:转为“axis coords”
plt.text(0.5,0.5,'Center Country',horizontalalignment='center',verticalalignment='center',transform=plt.gca().transAxes,fontsize=25) # horizontalalignment可以简写为"ha",verticalalignment可以简写为"va"
# 要使文本在正中,ha和va参数必不可少,尝试去掉就明白了,因为默认情况下的居中是以文本的左下角居中
函数原型:matplotlib.pyplot.annotate(s, xy, *args, **kwargs)
参数说明:
xy参数是一个二元组,表示被注释的点的位置坐标(x,y),实现最简单的应用:annotate(s,xy),即“用s标注点(x,y)”。当仅用于该用途时,(x,y)就是标注文本的左下角坐标。
xytext是一个二元组,可选参数,表示注释文本的位置坐标,默认与xy值相同,和xy参数一起用以配合arrowprops参数设置指向箭头。其中xy表示箭头位置坐标,xytext表示箭尾位置坐标,在arrowprops的字典中无arrowstyle键时,确实是这样,如果通过arrowstyle设置箭头,那么还可以以xy为箭尾,以xytext为箭头。
箭头:
arrowprops参数是一个字典,若不包含arrowstyle键,则以下键是允许的: width(箭宽)、 headwidth(箭头宽)、 headlength(箭头长)、 shrink(箭的两端收缩总长的一部分(百分制),用来控制标注和箭两端之间小的空隙)、 ?(Any key to matplotlib.patches.FancyArrowPatch); 否则,arrowprops字典中不能含有前述键,arrowstyle键的取值为:'-'、'->'、'-['、'|-|'、'-|>'、'<-'、'<->'、'<|-'、'<|-|>'、'fancy'、'simple'、'wedge',其他有效的键还可以是(参考译文): connectionstyle (the connection style)、 relpos (default is (0.5, 0.5))、 patchA (default is bounding box of the text)、 patchB (default is None)、 shrinkA (default is 2 points)、 shrinkB (default is 2 points)、 mutation_scale (default is text size (in points))、 mutation_aspect (default is 1.)、 ? (any key for matplotlib.patches.PathPatch)
xycoords可选参数,可以是str, Artist, Transform, callable 或 tuple。该参数用于设置参数xy所处的坐标系,之前在text()中已经初步接触过data coordinates和axis coords,这里我也不想多说,实在看不下去这破文档了,我只提一下xycoords参数可取的一个字符串值:"polar",表示“极坐标系”,有一点很奇怪的是:如果当前plot本身就是极坐标系(polar coords),那么再使用该参数并设置为"polar"就会出错,但如果当前plot是直角数据坐标系(data coords),那么指定xycoords='polar'就可以正常工作
textcoords可选参数,可以是str, Artist, Transform, callable 或 tuple。该参数用于设置参数xytext所处的坐标系,其取值同xycoords,并且还允许两种属性值:'offset points'(相对于被注释点xy的偏移量(单位是点))和'offset pixels' (相对于被注释点xy的偏移量(单位是像素))
kwargs关键字参数用于其他设置Text文本外观选项
x=[0,2,4,6]
y=[2,4,8,16]
plt.plot(x,y,marker='o',markersize=10,c='gray',markerfacecolor='green')
plt.plot([4],[8],marker='o',markersize=12,markerfacecolor='red')
plt.annotate('zhangjingjing',(3.35,7),bbox=dict(boxstyle='circle',facecolor='pink',ec='pink',alpha=0.7)) # 如何画心形注解框?
plt.annotate('muggledy loves you',(4,8),(6,10),arrowprops=dict(facecolor='pink',shrink=0.08,width=1,headwidth=6),color='green') # shrink收缩箭长的8%
plt.annotate('daiyang loves you',(3.9,8.25),(2,12),arrowprops=dict(arrowstyle='wedge',linestyle='-.',shrinkA=15,shrinkB=15),color='blue') # shrinkA和shrinkB设置箭两端的缩进,单位为points,注意和上一行代码中的shrink是不一样的,linestyle键出自“?”( matplotlib.patches.PathPatch)
plt.subplot(111,polar=True) # 当前plot本身是极坐标系
#plt.grid() # 默认极坐标就是显示网格线的,所以执行plt.grid()会关闭它
plt.annotate('V',xy=(0.5*np.pi,0.4),color='red') # plt.annotate('V',xy=(0.5*np.pi,0.4),xycoords='polar',color='red')出错,注释掉第一行代码就正确了
# 绘制心形线:ρ=a(1-cosθ)
theta=np.arange(0,2*np.pi,0.05) # θ
p=0.5*(1-np.sin(theta)) # ρ
plt.plot(theta,p)
plt.annotate('Cardioid',xy=(theta[-1],p[-1]),xytext=(theta[8],p[8]+1),arrowprops=dict(arrowstyle='->'))
函数原型:matplotlib.pyplot.title(label, fontdict=None, loc='center', pad=None, **kwargs)
参数说明:
label参数是标题文本
fontdict参数是一个控制标题外观的字典,默认值为:{'fontsize': rcParams['axes.titlesize'], 'fontweight' : rcParams['axes.titleweight'], 'verticalalignment': 'baseline', 'horizontalalignment': loc}
loc参数:{'center', 'left', 'right'}
pad参数设置标题与axes顶部的距离,单位为points,默认值为rcParams['axes.titlepad']
kwargs关键字参数设置其他Text文本外观属性
函数原型:matplotlib.pyplot.suptitle(t, **kwargs)
参数说明:
t参数:标题文本
x参数:float, default 0.5,表示的是在figure coordinates下文本的x坐标,是一个figure fraction分数(百分比)
y参数:float, default 0.98,表示的是在figure coordinates下文本的y坐标
horizontalalignment,ha参数:{'center', 'left', right'}, default: 'center',标题文本相对于(x,y)的水平对齐方式,默认为'center',表示文本的中心正处于位置(x,y),'right'表示文本的右端处于(x,y)位置
verticalalignment,va参数:{'top', 'center', 'bottom', 'baseline'}, default: 'top',类同上
fontsize,size参数:default: rcParams["figure.titlesize"]
fontweight,weight参数:default: rcParams["figure.titleweight"]
fontproperties参数:None or dict, optional 字典?怎么用?
其他kwargs关键字参数,用于设置matplotlib.text.Text
plt.figure(facecolor='pink') # plt.gcf().set_facecolor('pink')
plt.suptitle('suptitle',x=0.5,y=0.98,color='red',size=20)
plt.plot()
函数原型(以xlabel为例):matplotlib.pyplot.xlabel(xlabel, fontdict=None, labelpad=None, **kwargs)
参数说明:
xlabel参数设置标签文本
labelpad参数设置标签与x轴之间的间距
kwargs关键字参数设置标签文本Text外观
函数原型:matplotlib.pyplot.legend(*args, **kwargs)
Call signatures:legend()legend(labels)legend(handles, labels)
注:以上三种调用方式,对于完全的MATLAB风格编程者来说,只能使用第一种,后两种用于面向对象。其他可选参数:
loc参数设置legend的位置,主要记住6种可取值:字符串 代码'best' 0'upper right' 1'upper left' 2'lower left' 3'lower right' 4center 10
可取值'best'并不受推荐,当存在大量数据的绘图时,可能拖慢速度。
loc参数可取一个二元组,(0,0)表示左下角、(0.5,0.5)表示中央、(1,1)表示右上角(实际上就是"figure fraction"类型值),二元组允许你更改legend所在的任意位置(在这种情况下,bbox_to_anchor将被忽略)
bbox_to_anchor参数,可取值: BboxBase, 2-tuple 或 4-tuple of floats.
这玩意儿配合loc参数使用,且只当loc参数不使用二元组时起效,bbox_to_anchor用来选取一个指定区域(一个长方形区域),然后由loc在此区域中定位legend的放置位置(左上、右上、坐下、右下、最佳等)。举例说,假使我们面前有一个分为四个象限的直角坐标系,我们可以指定右下象限为legend的放置区域,当指定loc为'upper left'时候,legend就出现在右下限区域的左上角。bbox_to_anchor参数的取值,可以是一个四元组,含义为:(x, y, width, height),x,y,width,height的取值为"figure fraction"(一个分数、表示百分比),x,y表示长方形区域的左下角坐标,指定右下象限方形区域:(0.5,0,0.5,0.5),x=0.5和width=0.5表示x轴长的一半、y=0那就是0,height=0.5表示y轴长的一半
bbox_to_anchor参数的取值,还可以是一个二元组(x,y)(仍为"figure fraction"),配合loc,若loc为'lower left',表示:legend框的左下角的位置为(x,y),若loc为'upper right',表示:legend框的右上角位于(x,y)位置处。
其他参数见文档(例见"Nested pie charts")
第一种调用方式并不能满足需求,它只能工作在,每次plot()只绘制一条线且设置label的情况下,如果我们一次性在plot()中绘制了多条线,这时候,怎么为每一条线分别设置label呢?第一种解决办法就是通过内省机制setp()来完成;第二种,在线条对象上直接调用set_label()方法;第三种就是我们legend()的第二和第三种调用方式。
第二种,首先获取要设置标签属性的线条所在的axes轴域对象,然后在该axes上调用legend(),传入标签列表,其顺序与plot中线条绘制的顺序一致:axes.legend(['label 1','label 2',...])
第三种,更加灵活,接受两个参数,第一个是全部要设置标签属性的对象列表,第二个是对应的标签列表
plt.xlabel('x-axis',labelpad=20,fontfamily='fantasy',fontsize=20)
plt.ylabel('y-axis',labelpad=35,fontfamily='sans-serif',fontsize=20,rotation='horizontal')
plt.title('Theme',loc='right',pad=20)
plt.plot([5,3,7],label='a line') # legend中显示的文本将自动从此获取,姑且认为legend的文本为线条的label
plt.plot([0.5],[4],marker='*',markersize=15,label='a star',linestyle='')
plt.legend(loc=(0.72,0.23))
plt.annotate('One-to-one symbols and annotations \n ,and highlighted',xy=(0.8,0.48),xycoords='figure fraction',xytext=(0.27,0.65),arrowprops=dict(arrowstyle='simple',shrinkA=15),fontsize=15)
# 绘制正圆:x^2+y^2=4
x=np.arange(-2,2.01,0.01) # 由于arange()不包含end,所以end应设为end+step,通常我们用linspace:np.linspace(-2,2,100)
y=np.sqrt(np.fabs(4-x*x)) # fabs()绝对值不可省略,因为存在计算精度误差的问题,所以理论上可行而实际不可行,按理说是不需要fabs()的
plt.plot(x,y,c='black',label='a circle')
plt.plot(x,-y,color='black')
plt.legend(loc='upper right',bbox_to_anchor=(0.5,0.,0.5,0.5))
plt.annotate('Ellipse?',(0,0),ha='center',va='center',fontsize=20) # 使文本处于正中央,其中(0,0)是"data coords"
plt.annotate('How To Solve It?',(0,0),(1,1),arrowprops=dict(arrowstyle='simple',shrinkA=20,shrinkB=40),color='red',fontsize=25)
plt.axvline() # 沿轴垂线,参见spines移动脊柱,实际上,我本就是要的这种效果,但此前并不知道spines
plt.axhline() # 沿轴水平线
plt.annotate('right lower quadrant',(1,-1),(1.5,-1.8),arrowprops=dict(arrowstyle='simple',facecolor='pink',shrinkA=20),color='red',fontsize=15)
plt.fill([0,2,2,0],[-2,-2,0,0],color='gray')
# 解决:通过设置figure size可以使其“正”一点,还有其他办法吗?另一种办法是执行命令:plt.axis('equal'),具体请移步"plt.axis()"部分
plt.figure(figsize=(4,4)) # 在旧电脑上(2011年产)出现的问题:若取(4,4)还是显得扁了点,所以取(4,5),大概是因为显示器的问题?
x=np.arange(-2,2.01,0.01)
y=np.sqrt(np.fabs(4-x*x))
plt.plot(x,y,c='black',label='a circle')
plt.plot(x,-y,color='black')
plt.plot([9,7,5,3,1],label='slash')
plt.legend(loc='lower left',bbox_to_anchor=(0.5,0.5)) # legend框的左下角出现在(0.5,0.5)位置
index=range(6)
lines=plt.plot(index,np.random.randint(5,15,6),index,np.random.randint(5,15,6),index,np.random.randint(5,15,6))
ax=plt.gca()
labels=['line 1','line 2','line 3']
# 第二种调用方式
#ax.legend(labels)
# 第三种调用方式
plt.legend(lines,labels)
函数原型:matplotlib.pyplot.setp(obj, *args, **kwargs)
譬如要将线条的linestyle属性设置为虚线,可以这么做:line,=plt.plot([1,2,3])plt.setp(line,linestyle='--')
如果你想知道对象属性的有效值,可以提供该属性的名称:plt.setp(line,'linestyle')
如果你想知道对象上的全部可设置的属性以及可取的值,可以:plt.setp(line)
当控制台的定向输出(sys.stdout)因为某些原因而不可获得时,可以使用file关键字参数将结果定向输出到指定文件中:with open('xxx.txt') as f: plt.setp(line,file=f)
setp()在单个实例或者实例的可迭代序列上操作,如果当前处于查询模式,即正在内省对象属性的可能取值,那么只使用序列中的第一个实例,如果是在设置对象属性,那么设置将在序列中的全部对象上生效
setp()支持传递MATLAB风格的“属性字符串-值”对以及python的关键字参数,譬如以下是等效的:plt.setp(lines,'linewidth',2,'color','red') # MATLAB styleplt.setp(lines,linewidth=2,color='red') # python style
在使用plt.plot()绘制线形图后,函数返回所绘线条对象。我们在plot()中传递了诸多线条属性用以控制生成的线条外观,但正如罗马不是一日建成的,线形图也可能需要几经修改,pyplot模块提供了必需的命令接口用以控制基本的外观属性的配置和修改,譬如xlim()、xticks()等,同时提供了对象方法用以控制全部的外观属性,在对象上配置和修改属性主要有三种方法:
obj.set_属性名(值)obj.set(属性名=值)plt.setp(对象,属性名=值)代码示例:
line = plt.plot(range(5))[0]
line.set_color('r')
line.set_linewidth(2.0)
# 或者:
line.set(color = 'g',linewidth = 2.0)
# 或者:
plt.setp(line, color = 'g',linewidth = 2.0)
对象属性使用dir()查看,对象文档使用help()
lines=plt.plot(np.random.randint(5,15,6))
plt.setp(lines,linestyle='--')
plt.setp(lines,'linestyle') # 将列举出全部有效值(查询模式)
函数原型:matplotlib.pyplot.axvline(x=0, ymin=0, ymax=1, **kwargs)
axvline():ax:axes,v:vertical
参数说明:首先我们说明几个概念,在axis()中我们可以设置plot的x轴和y轴的刻度范围:xmin,xmax,ymin,ymax,于是平行于x轴的两条水平线y=ymin和y=ymax设置了axes(轴域)的“下边线”和“上边线”(我们姑且这么称呼哈),平行于y轴的垂线x=xmin和x=xmax设置了axes的“左边线”和“右边线”,xmax-xmin的值称为axes的“轴域宽”,ymax-ymin称为axes的“轴域高”。回到本函数中,参数x设置垂线的x轴坐标,参数ymin、ymax设置垂线的下端点和上端点相距于“下边线”的位置,取值为一个介于0到1的小数(百分比),譬如ymin取0,表示下端点距离下边线的距离为0,ymin取0.5表示下端点距离下边线的距离为“轴域高”的二分之一,ymax取0.9表示上端点距离下边线的距离为轴域高的0.9倍。
函数原型:matplotlib.pyplot.axhline(y=0, xmin=0, xmax=1, **kwargs)
axhline():ax:axes,h:horizontal
类同于axvline()的参数,axhline的参数y设置水平线的y轴坐标,xmin、xmax设置水平线的左端点和右端点相距于“左边线”的位置,譬如xmin取为0.5表示左端点距离左边线的距离为“轴域宽”的二分之一,xmax取值1表示右端点距离左边线的距离为一整个“轴域宽”。
xl,xr,yb,yt=plt.axis([-3,5,-4,7]) # x,y轴刻度范围
xlen=xr-xl # x轴长(轴域宽)
ylen=yt-yb # y轴长(轴域高)
p=ylen/2+yb # y轴中间位置
vl=plt.axvline(ymin=0.2,ymax=0.8,color='red') # 中间的那条垂线(红色)
hl=plt.axhline(p,xmin=0.1,xmax=0.9,color='purple') # 中间的那条水平线(紫色)
vlb,vlt=ylen*vl._y+yb # 计算vl线的下上端点在y轴上的坐标
hll,hlr=xlen*hl._x+xl # 计算hl线的左右端点在x轴上的坐标
plt.axvline(hll,ymin=0.2,ymax=0.8)
plt.axvline(hlr,ymin=0.2,ymax=0.8)
plt.axhline(vlb,xmin=0.1,xmax=0.9)
plt.axhline(vlt,xmin=0.1,xmax=0.9)
plt.annotate('({0:.1f},{1:.1f})'.format(0,p),(0,p)) # 显示位置坐标
plt.annotate('({0:.1f},{1:.1f})'.format(hll,vlt),(hll,vlt))
plt.annotate('({0:.1f},{1:.1f})'.format(hll,vlb),(hll,vlb))
plt.annotate('({0:.1f},{1:.1f})'.format(hlr,vlt),(hlr,vlt))
plt.annotate('({0:.1f},{1:.1f})'.format(hlr,vlb),(hlr,vlb))
函数原型:matplotlib.pyplot.hlines(y, xmin, xmax, colors='k', linestyles='solid', label='', *, data=None, **kwargs)
参数说明:
y参数:单个标量或者序列。譬如[y1,y2,...ym],将绘制m条水平线段,所在直线分别为y=y1,y=y2,...,y=ym
xmin,xmax参数指定每条线段的开头和结尾在x轴上的坐标,xmin和xmax可能是单个标量也可能是序列,这得看要绘制多少条水平线(一条的话就是单个标量),譬如第一条线段的开头x坐标为3,结尾为5,第二条开头为1,结尾为7,第三条开头为4,结尾为9,则xmin为[3,1,4],xmax为[5,7,9]
color参数可以设置每一条水平线的颜色,可以是一个序列
linestyles参数:{'solid', 'dashed', 'dashdot', 'dotted'}, optional
label参数:string, optional, default: ''
kwargs关键字参数设置LineCollection属性
plt.hlines([1,2,3,4,5],[1,2,3,4,5],[3,4,5,6,7],['red','green','blue','yellow','gray'],linestyles=['dashdot','solid','dashed','solid','dotted'])
函数原型:matplotlib.pyplot.vlines(x, ymin, ymax, colors='k', linestyles='solid', label='', *, data=None, **kwargs)
参数见hlines()
plt.vlines([1,2,3,4,5],[1,2,3,4,5],[3,4,5,6,7],['red','green','blue','yellow','gray'],linestyles=['dashdot','solid','dashed','solid','dotted'])
函数原型:matplotlib.pyplot.fill(*args, data=None, **kwargs)
参数说明:
args可变位置参数:可以指定多组x, y, [color]的组合,color是可省的,注意顺序不要弄错。我们知道构成一个多边形区域的最初元素就是几个点,将点逐一连接于是就得到了一个多边形区域,这些点正是由x、y参数指定的,它们都是序列对象,x是全部点在x轴上坐标的有序集合,y是全部点在y轴上坐标的有序集合。连线的顺序为:从第一个点出发连接第二个点,再从第二个点出发连接第三个点,以此类推(理论上讲我们现在可以画任意图像了而不仅仅是简单几何图案),其中点的顺序由此确定:zip(x,y),其得到一个二元组序列,每一个二元组表示一个坐标点,列表第一项就是第一个点,第二项就是第二个点,... 若不能构成封闭区域,那么总是自动将起点和终点以直线连接起来,由此构成封闭区域
函数调用譬如:fill(x,y) # 确定一个多边形区域,填充颜色为default colorfill(x1,y1,x2,y2,'b') # 确定两个多边形区域,其中第二个区域的颜色为蓝色
kwargs参数设置Polygon属性
data参数尚不清楚
星形线:$x^\frac{2}{3}+y^\frac{2}{3}=a^\frac{2}{3}$
# 绘制第一象限的星形线,根据对称性,得到其他象限星形线片段
a=2 # 取a为2
x=np.linspace(0,a,100)
y=np.power(np.power(2,2/3)-np.power(x,2/3),1.5)
plt.plot(x,y)
plt.plot(-x,y)
plt.plot(x,-y)
plt.plot(-x,-y)
# 填充四个边角区域
x1=np.concatenate((x,[2,0]))
y1=np.concatenate((y,[2,2]))
x2=np.concatenate((-x,[-2,0]))
y2=np.concatenate((y,[2,2]))
x3=np.concatenate((x,[2,0]))
y3=np.concatenate((-y,[-2,-2]))
x4=np.concatenate((-x,[-2,0]))
y4=np.concatenate((-y,[-2,-2]))
plt.fill(x1,y1,x2,y2,x3,y3,x4,y4)
# end终点和start起点直连才构成的封闭区域,填充它们完事儿
x=np.linspace(0,4*np.pi,500)
y=np.sin(x)
plt.fill(x,y,color='#bdf3d4')
plt.plot([x[0],x[-1]],[y[0],y[-1]],marker='.',color='black',linestyle='')
plt.annotate('start',(x[0]+0.1,y[0]+0.1))
plt.annotate('end',(x[-1]+0.1,y[-1]+0.1))
函数原型:matplotlib.pyplot.fill_between(x, y1, y2=0, where=None, interpolate=False, step=None, *, data=None, **kwargs)
默认y2=0,即填充x范围内曲线y1与x轴之间的区域。
参数说明:
x参数是两个函数共同的在x轴上点的取值集合,y1是函数曲线的对于自变量x的因变量的取值集合,y2同理。因此y1、y2和x的序列长度一致;特别地,y1和y2允许是标量,即单个整数值,这表示其为一条平行于x轴的水平线。
where参数:array of bool (length N), optional, default: None
where参数是一个条件阈值,接受一个条件表达式,返回结果应为一个一维布尔数组。含义:对于两个函数之间的区域,符合条件则填充,不符合则不填充。
interpolate和step参数:不理解
kwargs关键字参数用于设置其他 Polygon属性
x=np.linspace(0,2*np.pi,100)
y1=np.sin(x)
y2=np.cos(x)
sinx,cosx=plt.plot(x,y1,x,y2)
sinx.set_label('sin(x)') # 混合编程(分清主次)是最优的选择
cosx.set_label('cos(x)')
plt.legend()
plt.fill_between(x,y1,y2,where=y1<y2,color='lightgray')
plt.fill_between(x,y1,y2,where=y1>y2,color='pink')
plt.minorticks_on()
plt.grid(axis='x',which='both')
# 这个语句最大的问题是,背离了函数的本意,即两个函数曲线之间区域的填充,重点是函数曲线,函数的自变量x的变化应总是向着x轴正方向的
plt.fill_between([1,3,-2],[2,5,7],color='gray') # 所以[1,3,-2]是不合理的,it will not be in line with expectation
# 另外我们可以看出,两条曲线是如何构成封闭区域的:将曲线1和曲线2的左端点连接起来,将曲线1和曲线2的右端点连接起来,于是构成的封闭区域
# 而其确定左右端点的依据,就是(x[0],y1[0]),(x[0],y2[0]),(x[-1],y1[-1]),(x[-1],y2[-1])
# 绘制正态概率密度函数
mu=0
sigma=1
radius=5
x=np.linspace(mu-radius,mu+radius,100)
def f(x,mu,sigma):
return 1/(np.sqrt(2*np.pi)*sigma)*np.power(np.e,-(np.power((x-mu),2)/2*np.power(sigma,2)))
y=f(x,mu,sigma)
ymax=np.max(y)
plt.plot(x,y)
ax=plt.gca()
ax.spines['left'].set_position(('data',0))
ax.spines['bottom'].set_position(('data',0))
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
plt.yticks([])
#plt.xticks([mu+i*sigma for i in range(-3,4)],[i for i in range(-3.4)]) # 以前考研的时候我是万分期待敲代码的时光,虽然我有一颗撞南墙的心,但是今天实在是太过痛苦,无穷无尽的挫败感,使我绝望,搞了一天pelican,不过想部署一下博客,结果一事无成,到处都是错误,昏了头了,艹
# 我是真的醉了,我花了老大的功夫,才找出上述代码的错误,简直不可想象,我甚至都开始觉得我TM还适合这个行业?我尼玛也太蠢了点。。。
plt.xticks([mu+i*sigma for i in range(-3,4)],['0' if i==0 else '$\mu$'+('+'+str(i) if i>0 else str(i))+'$\sigma$' for i in range(-3,4)])
mu_one_sigma=f(mu+sigma,mu,sigma)
mu_two_sigma=f(mu+2*sigma,mu,sigma)
mu_three_sigma=f(mu+3*sigma,mu,sigma)
plt.fill_between(x,y,where=y>=mu_one_sigma,color='g',alpha=0.8)
plt.fill_between(x,y,where=y>=mu_two_sigma,color='g',alpha=0.5)
plt.fill_between(x,y,where=y>=mu_three_sigma,color='g',alpha=0.2)
plt.title('$3\sigma$法则')
def cc(color,alpha):
return mcolors.to_rgba(color, alpha)
plt.annotate('68.3%',(mu+(2/3)*sigma,(3/5)*ymax),(mu+2*sigma,(3/5)*ymax+0.05),arrowprops=dict(arrowstyle='->',fc='g',ec=cc('g',alpha=0.8)),color=cc('g',alpha=1))
plt.annotate('95.5%',(mu+(2/3)*2*sigma,(1/4)*ymax),(mu+2.7*sigma,(1/4)*ymax+0.05),arrowprops=dict(arrowstyle='->',ec=cc('g',alpha=0.5)),color=cc('g',alpha=0.7))
plt.annotate('99.7%',(mu+(4/5)*3*sigma,(1/100)*ymax),(mu+3.6*sigma,(1/1001/4)*ymax+0.05),arrowprops=dict(arrowstyle='->',ec=cc('g',alpha=0.2)),color=cc('g',alpha=0.4))
plt.annotate('$x\sim N$'+'({0},{1})'.format(mu,sigma),(mu-3.5*sigma,(2/3)*ymax),fontsize=13)
plt.annotate(r'$f(x)=\frac{1}{\sqrt{2\pi}\sigma}e^{-\frac{(x-\mu)^2}{2\sigma^2}}$',(mu+2*sigma,ymax),fontsize=15) # 靠,LaTeX加'r'原始字符串啊!忘

函数原型:matplotlib.pyplot.fill_betweenx(y, x1, x2=0, where=None, step=None, interpolate=False, *, data=None, **kwargs)
默认x2为0,表示填充x1与y轴之间的区域
该图像绘制,应以y为自变量,x为因变量,即首先写出反函数。
参数说明类似fill_between()
x=np.linspace(-0.5*np.pi,0.5*np.pi,100)
y=np.sin(x)
plt.plot(x,y,color='red')
plt.fill_betweenx(y,x,color='pink')
plt.axvline(ymin=0.05,ymax=0.95)
plt.annotate('$x=0$',(0,0.75)) # matplotlib中任何Text文本都允许嵌入LaTeX表达式,但记得加上'r'原始字符串标识,这是因为排版公式时,字符串所包含的内容必须按照 TeX 的规范,而不是其他的规范,来进行解析。所以使用 raw string 可以避免其它规则解释字符串中某些特殊字符所带来的歧义。
plt.annotate(r'$x=arcsiny$',(1,0.75))
plt.minorticks_on()
plt.grid(axis='y',which='both')
x=np.linspace(-0.5*np.pi,np.pi,100)
y=np.sin(x)
plt.plot(x,y,color='red')
plt.fill_betweenx(y,x,color='pink')
plt.axhline(0.5)
plt.plot([(1/6)*np.pi,(5/6)*np.pi],[1/2,1/2],marker='.',color='black',linestyle='')
plt.annotate(r'when y=$\frac{1}{2}$, x=$\frac{1}{6}\pi$ or $\frac{5}{6}\pi$ ?',(-1,0.75),fontsize=15)
plt.annotate(' Not one-to-one mapping,\nand not in line with expectation',(1,-0.5),fontsize=16,color='r')
函数原型:matplotlib.pyplot.axvspan(xmin, xmax, ymin=0, ymax=1, **kwargs)
参数说明:
xmin,xmax:标量,描述自变量跨度范围
ymin,ymax:标量,可选,描述长方形的高度范围,默认xmin=0,xmax=1,一个分数(相对于axes高度的百分比),0-1,前者表示长方形底部位于axes底部,后者表示长方形顶部位于axes顶部,若ymax取值0.5,则长方形顶部位于axes中部
函数原型:matplotlib.pyplot.axhspan(ymin, ymax, xmin=0, xmax=1, **kwargs) 参数说明:
ymin,ymax,xmin,xmax:类同axvspan()
# 高亮
xmin,xmax=-np.pi,3*np.pi
x=np.linspace(xmin,xmax,100)
y=np.sin(x)
plt.plot(x,y)
ax=plt.gca()
ax.spines['left'].set_position(('data',0))
ax.spines['bottom'].set_position(('data',0))
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
xticks=np.linspace(xmin,xmax,int((xmax-xmin)/np.pi+1)) # 第三个参数必须是整数,但实参为浮点数计算,要手动转换为int,否则给出警告:DeprecationWarning: object of type <class 'float'> cannot be safely interpreted as an integer.
plt.xticks(xticks,[str(int(i/np.pi))+('' if int(i/np.pi)==0 else '$\pi$') for i in xticks])
plt.yticks([-1,1])
plt.axvspan(1.5*np.pi,2.5*np.pi,color='purple',alpha=0.7)
plt.axhspan(-0.5,0.5,color='gray',xmin=0.27,alpha=0.4)
函数原型:matplotlib.pyplot.arrow(x, y, dx, dy, **kwargs)
参数说明:绘制出一个从点(x, y)指向到点(x+dx, y+dy)的箭头。
kwargs关键字参数用于设置FancyArrow属性
plt.axis([0,10,0,10])
plt.arrow(1,1,2,2,fc='r',ec='b',width=0.2,head_width=2,head_length=5,linestyle='--',linewidth=2) # fc:facecolor,ec:edgecolor
函数原型:matplotlib.pyplot.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, *, data=None, **kwargs)
参数说明:
x参数:array-like(类似数组对象,如numpy中的ndarray、python原生列表及其嵌套等)或者PIL(Python Imaging Library)图像(Python图像处理标准库)。合法的数组形状:
m,n决定了图像的行数和列数(图像的高、宽),RGB或RGBA颜色应为处于[0,1]范围的小数或者[0,255]范围的整数,超出范围的一律剪为边界值
cmap参数:str or Colormap,Colormap将x的前两个维度的scalar data(标量数据)映射到色域中的颜色,缺省值为rcParams["image.cmap"]
aspect参数:{'equal', 'auto'} or float, optional,控制轴域axes的纵横比,与图像显示特别相关,因为它可能会扭曲图像,即像素点不是方形的了。此参数是显式调用Axes.set_aspect()的快捷方式。
若参数未给出,将使用rcParams["image.aspect"](default: 'equal')
norm、vmin,vmax参数:参见pcolor
origin参数:上下翻转二维数组x,实际上就是沿着0轴(长为n)进行 x[i] 和 x[n-i-1] 位置的元素置换,可以使x[0][0]位于左上角或左下角,默认取值'upper',当取'lower'时,x[0][0]将位于左下角
extent、其他参数:看不懂
# "Colormap Reference"一条小彩条的完整绘制过程(此处使用imshow(),当然使用plt.bar()也可以,另见)
plt.subplot(111)
plt.subplots_adjust(bottom=0.95,top=1)
a=np.linspace(0,1,256).reshape(1,256)
c=plt.get_cmap('Set1')
plt.imshow(a,cmap=c,aspect='auto')
plt.axis('off')
a=np.arange(18).reshape(3,6)
plt.imshow(a,cmap='cool') # 从中我们可以看出,对于一个m*n的二维图像(3*6),它是怎么显示的(0轴对应y轴,1轴对应x轴)
plt.colorbar(shrink=0.5)
# 结合PIL显示图像(最基本)
im=Image.open('./matplotlib/DB/image/40.jpg')
plt.figure(figsize=(15,15)) # 设置画布大小,可以实现放大和缩小图片的目的,或者使用dpi参数。过大的数值将导致图像失真
plt.imshow(im,aspect='equal') # 设置为auto观察,你将看到人物两边被拉伸开来
函数原型:matplotlib.pyplot.pcolor(*args, alpha=None, norm=None, cmap=None, vmin=None, vmax=None, data=None, **kwargs)
Call signature:pcolor([X, Y,] C, **kwargs)
x,y参数可以将整个plot划分(方式:设置xticks(x)和yticks(y),然后延长这些刻度即可)成诸多的矩形网格,每个格子是一个四边形区域,设其左下角位置坐标为(x[i],y[j]),那么这个格子将用于存放和显示一种颜色(c[i][j]所映射的颜色)
c参数是一个二维的数组,其尺寸应比形状(len(y),len(x))还要大一圈,即(len(y)+1,len(x)+1)是最合理的(原因很简单,譬如说,5个格子我们需要6个刻度来标识啊),但是c的形状等于(len(y),len(x))也未尝不可,只不过c的最后一行和最后一列都将被省略,这些数据所映射的颜色将不会呈现出来。
颜色映射:系统会将c中的数据映射到cmap中,cmap即color map对应着一个色域,matplotlib内置了众多的色域。映射的过程分为两步,首先通过数据转换类Normalize或者其子类实例将数据源c缩放至区间[0,1]范围内的小数,默认情况下是线性缩放。这个步骤被称为标准化。然后Colormap的实例就会将0-1范围内的小数转换成cmap中的颜色。整个过程是依据data-> normalize-> map-to-color的处理链
cmap参数可以是字符串,也可以是Colormap的实例
vmin,vmax参数:一个典型的应用场景是,譬如我们有一批数据,想要将其映射至cmap,并呈现出来以对数据进行可视化观察和分析,令人懊恼的是,映射之后,我们发现每一个数据的颜色都差不多,远着看甚至看不出数据有任何区别,我们的常识告诉我们,应该对数据进行“放大处理”,将微小的区别放大,区别不就显而易见了嘛。之所以这批数据的颜色相仿,是因为这批数据的大部分都映射到了cmap中的一个很小的区域,假设这批数据本身的最大值和最小值分别为min和max,而数据的主要集中区域可以为submin和submax(有:submin>>min,submax<<max)所囊括,于是我们人为地设置vmin=submin,vmax=submax,在未设置的默认情况下,vmin=min,vmax=max。于是经过标准化处理之后,数据的主要部分将分布于整个色域,不会出现之前集中于色域一小块范围的情况。另外,对于区间min-submin之内的数据标准化之后全部是0,区间submax-max之内的数据标准化之后全部是1(小于vmin阈值的数据全部使等于vmin,大于vmax阈值的数据全部使等于vmax)。
注意:pcolor()对于大型数组来说可能非常慢。在大多数情况下,您应该使用类似但更快的pcolormesh()
其他参数见文档
x=[1,2,4,7,11,16]
y=x+[22]
plt.xticks(x)
plt.yticks(y)
plt.grid()
plt.axis([1,16,1,22])
plt.fill([7,11,11,7],[11,11,16,16])
plt.plot([7,7,11,11],[11,16,11,16],marker='.',color='black',linestyle='')
plt.annotate('(x[i],y[j])\n i=3,j=4',(6,8),fontsize=12)
plt.annotate('c[i][j]',(8.2,13),fontsize=12)
plt.annotate('(x[i],y[j+1])',(6,16.5),fontsize=12)
plt.annotate('(x[i+1],y[j])',(10,9.5),fontsize=12)
plt.annotate('(x[i+1],y[j+1])',(10,16.5),fontsize=12)
x=[1,2,4,7,11,16]
y=x+[22]
fig,ax=plt.subplots(2,2,sharey=True,sharex=True)
fig.set_figwidth(10)
fig.set_figheight(7)
ax[0,0].set_xticks(x)
ax[0,1].set_yticks(y)
# 关闭全部轴刻度
for i in [0,1]:
for j in [0,1]:
ax[i,j].axis('off')
# 替代方案
'''
for i in ax.flat:
i.set_axis_off()
'''
c=np.arange(len(x)*len(y)).reshape(len(y),len(x))
ax[0,0].pcolor(x,y,c,edgecolor='red',alpha=0.9)
ax[0,1].pcolor(x,y,c,cmap='coolwarm')
ax[1,0].pcolor(x,y,c,cmap='gray')
ax[1,1].pcolor(x,y,c,cmap='coolwarm',vmin=0,vmax=20)
c=np.random.rand(36).reshape(6,6)
plt.pcolor(c,cmap='autumn')
# 这里还没有看,代码来源于网络
# 如何只保留x轴的刻度,但不要y轴的?如果不行,那就用colorbar
grad=np.linspace(0,1,256)
grad=np.vstack((grad,grad))
plt.figure(figsize=(10,0.3))
ax=plt.subplot()
plt.xticks([0,100,250],[0,100,251])
plt.axis('off')
ax.imshow(grad,aspect='auto')
vmin和vmax参数说明: 
函数原型:matplotlib.pyplot.pcolormesh(*args, alpha=None, norm=None, cmap=None, vmin=None, vmax=None, shading='flat', antialiased=False, data=None, **kwargs)
Call signature:pcolor([X, Y,] C, **kwargs)
参数参见pcolor()
与pcolor()之间的区别:
主要区别在于创建的对象和内部数据处理:当pcolor()返回PolyCollection时,pcolormesh()返回QuadMesh。后者更专业于特定目的,因此更快。它应该几乎总是首选。...
靠,鬼读得懂!
Both methods are used to create a pseudocolor plot of a 2-D array using quadrilaterals.
The main difference lies in the created object and internal data handling: While pcolor returns a PolyCollection, pcolormesh returns a QuadMesh. The latter is more specialized for the given purpose and thus is faster. It should almost always be preferred.
There is also a slight difference in the handling of masked arrays. Both pcolor and pcolormesh support masked arrays for C. However, only pcolor supports masked arrays for X and Y. The reason lies in the internal handling of the masked values. pcolor leaves out the respective polygons from the PolyCollection. pcolormesh sets the facecolor of the masked elements to transparent. You can see the difference when using edgecolors. While all edges are drawn irrespective of masking in a QuadMesh, the edge between two adjacent masked quadrilaterals in pcolor is not drawn as the corresponding polygons do not exist in the PolyCollection.
Another difference is the support of Gouraud shading in pcolormesh, which is not available with pcolor.
函数原型:matplotlib.pyplot.set_cmap(cmap)
该设置适用于当前图像(current image)。参数cmap必须是一个Colormap实例,或者一个已注册的(matplotlib内置)colormap名称(譬如'autumn')。参见matplotlib.cm.register_cmap()和matplotlib.cm.get_cmap().
函数原型:matplotlib.cm.get_cmap(name=None, lut=None)
获取一个colormap实例,如果name为None,则默认为rc值。使用register_cmap()添加的colormaps(颜色映射)优先于内置的colormaps。如果name是一个Colormap实例,那么它就是函数返回值
If lut is not None it must be an integer giving the number of entries desired in the lookup table, and name must be a standard mpl colormap name.(不懂)
Reference for colormaps included with Matplotlib.
A reversed version of each of these colormaps is available by appending _r to the name, e.g., viridis_r.
See Choosing Colormaps in Matplotlib for an in-depth discussion about colormaps, including colorblind-friendliness.
# registed cmap
cmaps = [('Perceptually Uniform Sequential', [
' viridis', 'plasma', 'inferno', 'magma']),
('Sequential', [
' Greys', 'Purples', 'Blues', 'Greens', 'Oranges', 'Reds',
'YlOrBr', 'YlOrRd', 'OrRd', 'PuRd', 'RdPu', 'BuPu',
'GnBu', 'PuBu', 'YlGnBu', 'PuBuGn', 'BuGn', 'YlGn']),
('Sequential (2)', [
' binary', 'gist_yarg', 'gist_gray', 'gray', 'bone', 'pink',
'spring', 'summer', 'autumn', 'winter', 'cool', 'Wistia',
'hot', 'afmhot', 'gist_heat', 'copper']),
('Diverging', [
' PiYG', 'PRGn', 'BrBG', 'PuOr', 'RdGy', 'RdBu',
'RdYlBu', 'RdYlGn', 'Spectral', 'coolwarm', 'bwr', 'seismic']),
('Cyclic', [' hsv']),
('Qualitative', [
' Pastel1', 'Pastel2', 'Paired', 'Accent',
'Dark2', 'Set1', 'Set2', 'Set3',
'tab10', 'tab20', 'tab20b', 'tab20c']),
('Miscellaneous', [
'flag', 'prism', 'ocean', 'gist_earth', 'terrain', 'gist_stern',
'gnuplot', 'gnuplot2', 'CMRmap', 'cubehelix', 'brg',
'gist_rainbow', 'rainbow', 'jet', 'nipy_spectral', 'gist_ncar'])]
# 为了让它们对齐,我容易吗我?有没有办法解决?(去掉以上某些字符串中多余的空格,你就明白了,太影响审美了)
gradient = np.linspace(0, 1, 256)
gradient = np.vstack((gradient, gradient))
def plot_color_gradients(cmap_category, cmap_list):
# Create figure and adjust figure height to number of colormaps
nrows = len(cmap_list)
figh = 0.35 + 0.15 + (nrows + (nrows-1)*0.1)*0.22
fig, axes = plt.subplots(nrows=nrows, figsize=(6.4, figh))
fig.subplots_adjust(top=1-.35/figh, bottom=.15/figh, left=0.2, right=0.99)
axes=axes if isinstance(axes,np.ndarray) else np.array([axes])
axes[0].set_title(cmap_category + ' colormaps', fontsize=14)
for ax, name in zip(axes, cmap_list):
ax.imshow(gradient, aspect='auto', cmap=plt.get_cmap(name.strip()))
ax.text(-.01, .5, name, va='center', ha='right', fontsize=10,
transform=ax.transAxes)
# Turn off *all* ticks & spines, not just the ones with colormaps.
for ax in axes:
ax.set_axis_off()
for cmap_category, cmap_list in cmaps:
plot_color_gradients(cmap_category, cmap_list)
# 要使用以上的内置cmap:plt.cm.<cmap's name>([...]) 可获取color map的一部分颜色映射
# [...]序列元素取值一般取0-1范围之内的小数,以上小彩条的起点就是0,终点就是1,譬如取0.5就是中间的颜色,取0.25就是1/4处的颜色,这样对照着彩条,我们就可以取到合适的颜色
# 要获取整个color map: get_cmap("cmap's name")
colors=plt.cm.Set1(np.random.randint(0,10,20))
# 颜色展示(彩条)
def colorsBar(colors):
'''Show all colors via bar plot'''
n_colors=len(colors)
index=np.linspace(0,1,n_colors)
width=index[1]-index[0]
plt.figure(figsize=(7.5,0.3))
plt.bar(index,1,color=colors,width=width)
plt.xlim(0-0.5*width,1+0.5*width)
plt.axis('off')
colorsBar(colors)
colorsBar(plt.cm.gist_ncar(np.random.randint(0,300,100))) # 当然非0-1也是可以的,会被标准化至0-1空间
colorsBar(plt.cm.jet(np.arange(500)))
函数原型:matplotlib.pyplot.savefig(*args, **kwargs)
Call signature:savefig(fname, dpi=None, facecolor='w', edgecolor='w', orientation='portrait', papertype=None, format=None, transparent=False, bbox_inches=None, pad_inches=0.1, frameon=None, metadata=None)
The output formats available depend on the backend being used.(可用的输出文件格式依赖于当前使用的的后端)
参数说明:
fname参数:str or file-like object,一个字符串,包含指向文件的路径,或类似于python file的对象,或者可能是一些后端(backend)相关的对象,如 PdfPages。如果文件格式format为None,fname为文件名字符串,则从文件名的扩展名推断出输出格式。如果文件名没有扩展名,则使用rcparams[“savefig.format”]。如果fname不是字符串,请记住指定format参数以确保使用正确的后端。
其它参数:
dpi参数:None or scalar > 0 or 'figure',设置分辨率,单位为点数每英寸(dots per inch),如果为None,默认为rcParams["savefig.dpi"]。如果取'figure',则使用图像figure的dpi值
quality参数:None or 1 <= scalar <= 100,图像质量,取值从1(最差)到95(最好)。仅当格式为JPG或JPEG时适用,否则忽略。如果取值None,则默认为rcparams[“savefig.jpeg_quality”](默认为95)。应避免使用大于95的值;100 completely disables the JPEG quantization stage.(What?)
facecolor参数:color spec or None, optional,The facecolor of the figure; if None, defaults to rcParams["savefig.facecolor"].
edgecolor参数:color spec or None, optional,The edgecolor of the figure; if None, defaults to rcParams["savefig.edgecolor"]
orientation参数:{'landscape', 'portrait'},Currently only supported by the postscript backend.
papertype参数:str,可选值:'letter', 'legal', 'executive', 'ledger', 'a0' through 'a10', 'b0' through 'b10'. Only supported for postscript output.
format参数:str,可选值:后端支持的文件扩展名之一,大多数后端支持 png, pdf, ps, eps 和 svg。
下面我就读不懂了:
transparent参数:bool,If True, the axes patches will all be transparent; the figure patch will also be transparent unless facecolor and/or edgecolor are specified via kwargs. This is useful, for example, for displaying a plot on top of a colored background on a web page. The transparency of these patches will be restored to their original values upon exit of this function.
frameon参数:bool,If True, the figure patch will be colored, if False, the figure background will be transparent. If not provided, the rcParam 'savefig.frameon' will be used.
bbox_inches参数:str or Bbox, optional,Bbox in inches. Only the given portion of the figure is saved. If 'tight', try to figure out the tight bbox of the figure. If None, use savefig.bbox
pad_inches参数:scalar, optional,Amount of padding around the figure when bbox_inches is 'tight'. If None, use savefig.pad_inches
bbox_extra_artists参数:list of Artist, optional,A list of extra artists that will be considered when the tight bbox is calculated.
metadata参数:dict, optional,Key/value pairs to store in the image metadata. The supported keys and defaults depend on the image format and backend:
譬如轴域的背景色、图像保存时的fc:plt.rcParams['axes.facecolor']='green'plt.rcParams['savefig.facecolor']='white'
函数原型:matplotlib.pyplot.plot_date(x, y, fmt='o', tz=None, xdate=True, ydate=False, *, data=None, **kwargs)
类似于plot(),本函数可用于绘制线形图和散点图,区别在于,plot_dates()的轴标签的格式取决于xdate和ydate。
看不懂
函数原型:matplotlib.pyplot.plotfile(fname, cols=(0, ), plotfuncs=None, comments='#', skiprows=0, checkrows=5, delimiter=', ', names=None, subplots=True, newfig=True, **kwargs)
看不懂
函数原型:matplotlib.pyplot.bar(x, height, width=0.8, bottom=None, *, align='center', data=None, **kwargs)
参数说明:
将这些bars(柱)以指定的对齐方式(align)分别置于x坐标处,它们的尺寸由height和width(缺省为0.8)指出,其基线(柱bars的底部所在水平线)默认为0(水平线:y=0)。x、height、width和bottom都可以是单个标量适用于全部bars,也可以是长为N(柱的个数)的序列,用来为每一个bar提供属性值。
align参数:{'center', 'edge'}, optional, default: 'center'
'center': 柱的中心位于x位置处
'edge': 柱的左边缘与x对齐
要使柱的右边缘与x对齐,传递负的width值并置align='edge'
其他参数:
color:scalar or array-like, optional,(以单一颜色)设置全部bars的face color或为每一个bar单独设置(不同的颜色)
edgecolor:scalar or array-like, optional,设置全部bars的edge color或为每一个bar单独设置
linewidth:scalar or array-like, optional,设置全部bars的edge line width或为每一个bar单独设置,当为0时,不绘制边线
tick_label:string or array-like, optional,设置全部bars的label标签或为每一个bar单独设置,缺省为None,使用数字标签(刻度)
误差(另见errorbar()):
xerr,yerr:scalar or array-like of shape(N,) or shape(2,N), optional
xerr可以跳过,几乎用不到,看一下yerr就行,可以描述柱状图在y轴取值的误差(浮动)范围,或者用于描述均值与标准差、均值与标准误差、置信区间(一般用errorbar())。
单个标量scalar将适用于全部bar,每个bar的顶部在垂直方向上+/-一个scalar;形状(N,)的序列将为每个bar单独设置+/-的值;形状(2,N)的数组将为每个bar单独设置用于+的值以及用于-的值。
ecolor参数:scalar or array-like, optional,设置全部error bars的颜色或为每一个bar单独设置,缺省为黑色
capsize参数:我实在是无法描述这是个什么玩意儿,只要知道它接受一个标量,含义为长度,单位为point,譬如取10,就是10个像素点那么长,缺省时,取自rcParams["errorbar.capsize"],具体见实验
error_kw参数接受一个字典,就是对上述一系列参数进行一个打包,传递给errorbar(),其中的ecolor键或capsize键具有比在外面设置的相同关键字参数更高的优先级。
log参数:bool, optional, default: False,y轴刻度以对数计量
orientation参数:{'vertical', 'horizontal'}, optional,控制绘制的柱形图是垂直还是水平的,但是不被推荐,若希望绘制水平方向的柱状图,应使用barh()
其他关键字参数
返回值:
返回一个容器对象,BarContainer:Container with all the bars and optionally errorbars.(用help或者内省查看了一下,容器中的元素即bar是拥有label标签属性的,可以用于设置legend,通过setp()来设置)
# 随机数柱状图
n=8# 试着赋值100,,理论上允许绘制任意数量的bar
bars=[2*i+1 for i in range(n)] # 设置每个bar所在的刻度
colors=['red','blue','purple','green','gray','yellow','pink'] # 很多颜色,可以超出bars的个数
np.random.shuffle(colors)
'''
if n>len(colors):
colors+=[colors[-1]]*(n-len(colors))
'''
while n>len(colors): # 当n很大,不断重复颜色
colors+=colors[:n-len(colors)]
values=np.random.randint(5,20,len(bars))
plt.bar(bars,values,color=colors,tick_label=colors[:len(bars)])
for i in range(n):
plt.annotate('{0}'.format(values[i]),(bars[i]-0.3,values[i]+0.15))
ax=plt.gca()
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
plt.plot(bars,values)
# 四个柱的取值分别为2、4、1、3,第一个柱的浮动范围为[2-1,2+0.5]、第二个柱的浮动范围为[4-0.8,4+0.9]、第三个柱的浮动范围为[1-0.5,1+0.3]、第四个柱的浮动范围为[3-0.9,3+0.6]
plt.bar([0,2,4,6],[2,4,1,3],yerr=[[1,0.8,0.5,0.9],[0.5,0.9,0.3,0.6]],capsize=10,alpha=0.3)
plt.plot([2-0.2,2+0.2],[4.9,4.9],color='red')
plt.plot([2-0.2,2+0.2],[3.2,3.2],color='red')
plt.annotate('capsize parament',(2.5,4.8),color='red')
n_groups=5
means_men=(20,35,30,35,27) # 含义:均值
std_men=(2,3,4,1,2) # 含义:标准差
means_women=(25,32,34,20,25)
std_women=(3,5,2,3,3)
barwidth=0.3
index_men=np.arange(n_groups)
index_women=index_men+barwidth
# 绘制1
plt.subplot(121)
plt.bar(index_men,means_men,width=-barwidth,yerr=std_men,align='edge',label='men') # 为全部的蓝色bar设置同一的label标签,如果我们一次绘制的bars颜色各不相同,是否可以逐一设置label呢,是可以的,见"polar bar"
plt.bar(index_women,means_women,width=-barwidth,yerr=std_women,align='edge',label='women')
plt.legend()
plt.xticks(index_men,['first group','second group','third group','forth group','fifth group'],rotation=40)
plt.title('Scores by group and gender')
# 绘制2(bottom参数)
plt.subplot(122)
plt.bar(index_men,means_men,width=-barwidth,yerr=std_men,label='men',tick_label=['G1','G2','G3','G4','G5'])
plt.bar(index_men,means_women,width=-barwidth,yerr=std_women,bottom=means_men,label='women')
plt.legend()
# 调整子图大小和间距
plt.tight_layout(rect=(0,0,1.5,0.9))
# 绘制3
plt.subplots() # 准备新的figure(最大的画布单位,试着去掉此句看看结果)
plt.bar(index_men,means_men,width=1,yerr=std_men,label='men',color=plt.cm.cool(0.2),edgecolor='w')
plt.bar(index_men,[-i for i in means_women],width=1,yerr=std_women,label='women',color=plt.cm.winter(0.8),edgecolor='w')
plt.gca().set_facecolor('#F0F0F0')
plt.grid(axis='y')
plt.axhline(0,color='w')
# 靠,为什么这两种方法都出错???
# plt.gca().set_xticklabels(['G1','G2','G3','G4','G5']) # plt.setp(plt.gca().xticklabels,['G1','G2','G3','G4','G5'])
plt.xticks(index_men,['G1','G2','G3','G4','G5'])
A different appearance of bar graph.
plt.subplot(111,projection='polar') # 准备,创建一个极坐标画板,默认创建的是直角坐标画板
plt.bar(0.5*np.pi,3,width=0.25*np.pi) # 开始绘制,参数同直角系,此语句结果:在1/2π处(居中)绘制一个扇形,弧度由width参数指定,即1/4π ,扇形母线长度由height参数指定(第二个位置参数)指定,此处为3
# 绘制一批数据在极坐标下的“柱状图”(polar bar)
data=np.random.randint(5,15,8) # 试着修改第三个参数
# 要绘制polar bar,首先准备好bar index、bar height、bar width、bar color,前三项对应在极坐标下,就是:theta index、wedge radius、wedge radian
radian=2*np.pi/len(data)
radius=data
index=[(i+0.5)*radian for i in range(len(data))]
colors=['red','blue','purple','green','gray','yellow','pink']
while len(data)>len(colors):
colors+=colors[:len(data)-len(colors)]
while colors[0]==colors[-1] or colors[-1]==colors[-2]:
colors[-1]=np.random.choice(colors) # 防止两个相邻的楔形颜色相同
# 绘制
plt.subplot(111,projection='polar')
bars=plt.bar(index,radius,radian,color=colors)
# 通过内省为每一个颜色不同的bar设置对应的标签(我这里存在颜色相同的bar,所以仅作示例,教导如何使用罢了)
for index,bar in enumerate(bars):
plt.setp(bar,label='%2.1f'%data[index])
plt.legend(loc=(1.2,0.5),title='Values')
# 绘制matplotlib经典标志
n=20 # 设置柱的个数
# Fixing random state for reproducibility
np.random.seed(19680801) # 试着填入其它任意整数,譬如你的生日
# 三大参数
theta=np.linspace(0,2*np.pi,n,endpoint=False)
radius=np.random.rand(n)*10
#width=np.pi/n*1.2*2
width=np.pi/4*np.random.rand(n)
# 绘制polar bar
plt.subplot(111,projection='polar')
bars=plt.bar(theta,radius,width)
# Use custom colors and opacity(未仔细看)
for r, bar in zip(radius, bars):
bar.set_facecolor(plt.cm.viridis(r / 10.))
bar.set_alpha(0.5)
函数原型:matplotlib.pyplot.barh(y, width, height=0.8, left=None, *, align='center', **kwargs)
和bar()几乎没有任何区别,试想一下,将直角坐标系的x轴和y轴名字调换一下,bar()不就变成了barh()嘛
plt.figure(figsize=(4,2))
plt.barh(np.arange(0,2,0.5),[1,3,2,4],0.3)
函数原型:matplotlib.pyplot.pie(x, explode=None, labels=None, colors=None, autopct=None, pctdistance=0.6, shadow=False, labeldistance=1.1, startangle=None, radius=None, counterclock=True, wedgeprops=None, textprops=None, center=(0, 0), frame=False, rotatelabels=False, *, data=None)
参数说明:
pie()绘制数组x的饼图,默认情况下“饼”的半径为1,即总面积为π。每个楔形(扇形)的面积由数组元素x[i]与数组x的总和(sum(x))的比值决定,于是有:x_rate=x/sum(x),数组x_rate中存放的即是每个楔形面积与“饼”总面积的比值,这一过程称为“标准化”。但当sum(x)<=1时,每个楔形面积与“饼”总面积的比值就是x[i],此时毋须再标准化,特别地,当sum(x)<1时,“饼”不完整,存在空的楔形区域。
楔形是按照逆时针顺序绘制的,默认情况下是从x轴开始
explode参数:array-like, optional, default: None,每个楔形偏离“饼”心的程度,是一个分数。距离产生美,可以用于凸显某些楔形部分
labels参数:list, optional, default: None,为每一个楔形设置标签
colors参数:array-like, optional, default: None,为每一个楔形设置颜色
autopct参数:None (default), string, or function, optional,用于显示每个楔形所占比例,其置于楔形内部,默认不显示。它可以是一个(格式)字符串(譬如:'%d%%','%2.1f%%','%s%%'),也可以是函数。
pctdistance参数:float, optional, default: 0.6,设置autopct在楔形中的位置,默认值表示其显示的位置距离楔形的尖端为0.6(百分比,而默认楔形的母线长度即“饼”的半径就是1),当autopct为None时,该参数无效
shadow参数:bool, optional, default: False,是否为饼状图绘制阴影
labeldistance参数:float, optional, default: 1.1,描述楔形标签label与楔形尖端的距离
startangle参数:float, optional, default: None,楔形绘制的起点,默认为x-axis,此时startangle=0,角度沿逆时针递增,再次回到x-axis时,角度增至360度
radius参数:float, optional, default: None,“饼”的半径
counterclock参数:bool, optional, default: True,楔形绘制的方向,默认是逆时针,当取False时,为顺时针
wedgeprops参数:dict, optional, default: None,一个描述构成饼状图的楔形对象的字典参数,譬如wedgeprops={'linewidth':3},用于设置楔形边框线的宽度,另外width是一个神奇的属性,它用于绘制“环形饼”,其他属性自行查阅。
textprops参数:dict, optional, default: None,一个描述饼图中Text文本属性的字典参数
center参数:list of float, optional, default: (0, 0),Center position of the chart. Takes value (0, 0) or is a sequence of 2 scalars.
frame参数:bool, optional, default: False,为True则绘制出轴域axes框架
rotatelabels参数:bool, optional, default: False,为True则旋转每一个楔形的标签至所在楔形角度
返回值:
patches: list
全部的楔形对象(A sequence of matplotlib.patches.Wedge instances)
texts: list
全部的labels标签对象(是Text文本对象)(A list of the label matplotlib.text.Text instances)
autotexts: list
全部的autopct对象(也是Text文本)(A list of Text instances for the numeric labels. This will only be returned if the parameter autopct is not None.) 注意: 如果figure和axes是方形,或者axes的aspect参数取'equal',则饼图可能看起来最佳。此方法将轴的纵横比设置为“equal”。可以使用Axes.set_aspect()控制axes纵横比。
除了使用上述的关键字参数,还支持一个名为‘data’的关键字参数,该参数可用于替换以下参数:'colors', 'explode', 'labels', 'x',这样的'data'必须能够通过data[<arg>](譬如data['colors'])的方式访问,并且支持语法:<arg> in data
x=np.random.randint(5,15,6)
plt.subplot(121)
plt.pie(x)
plt.subplot(122)
plt.pie([0.12,0.14,0.2,0.1,0.16]) # 存在空缺楔形部分的饼图
plt.tight_layout(rect=(0,0,0.8,0.6)) # 当子图宽了或者扁了、大了或者小了的时候,进行修“正”
x=np.random.randint(5,15,6)
explode=[0.08,0.01,0.01,0.01,0.01,0.01]
labels=['muggledy','dongjiazhou','zhouqifei','liushaoliang','xiongzhengyao','liuwenwei']
colors=['red','blue','purple','green','gray','yellow','pink']
autopct='%2.1f%%' # 等同于函数:autopct=lambda x:'%2.1f%%'%x
plt.figure(figsize=(5,5))
plt.pie(x,explode=explode,labels=labels,colors=colors,autopct=autopct,wedgeprops=dict(edgecolor='black',linewidth=1),textprops=dict(color='black',fontsize=13,bbox=dict(boxstyle="round",ec=(1.,0.5,0.5),fc=(1.,0.9,0.8)))) # 感觉好难看~
#plt.gca().set_aspect('equal') # 我怎么没看出任何效果呢? # ax.set(aspect="equal", title='Pie')
plt.legend(loc=(1.2,0.6))
# 楔形对象的width属性:绘制圆环饼
plt.pie([1],wedgeprops=dict(width=0.5))
# 根据上面的“环”,我们大概有了思路,绘制两个这样的环,通过设置radius饼半径即可将另一个小环嵌套在大环内(you can accomplish the same output by using a bar plot on axes with a polar coordinate system.参见"Pie chart on polar axis")
out_ring=np.random.randint(5,15,6)
nested_ring=np.random.randint(5,15,6)
# 参数设置
labels=['A','B','C','D','E','F']
out_radius=1
nested_radius=0.7
out_width=out_radius-nested_radius
nested_width=out_width #
out_pctdistance=out_radius-0.5*out_width
nested_pctdistance=nested_radius
fmt='%2.1f%%'
# 颜色(尚未仔细看)
cmap=plt.get_cmap("tab20c")
colors=cmap(np.array([1,2,5,6,9,10]))
# 开始绘制
plt.figure(figsize=(5,5))
# 外环
wedges1,wedge_labels1,wedge_autopcts1=plt.pie(out_ring,wedgeprops=dict(width=out_width,ec='w'),radius=out_radius,colors=colors,autopct=fmt,pctdistance=out_pctdistance)
# 内环
*_,wedge_autopcts2=plt.pie(nested_ring,wedgeprops=dict(width=nested_width,ec='w'),radius=nested_radius,colors=colors,autopct=fmt,pctdistance=nested_pctdistance) # 解构,赋值号左边只能有一个*号,靠,我居然又忘了
# 标签(legend)
plt.legend(wedges1,labels,loc=(1.1,0.6),prop=dict(size='x-small',family='sans-serif',style='oblique'),shadow=True,facecolor='pink',title='List')
# (内省)设置Text颜色属性
plt.setp(wedge_autopcts1,color='r')
plt.setp(wedge_autopcts2,color='w')
# others
plt.annotate('PIE',(-0.13,-0.08),fontsize=20,alpha=0.5,color='r')
函数原型:matplotlib.pyplot.colorbar(mappable=None, cax=None, ax=None, **kw)
Function signatures for the pyplot interface; all but the first(plt.colorbar()) are also method signatures for the colorbar() method(fig.colorbar()):colorbar(**kwargs)colorbar(mappable, **kwargs)colorbar(mappable, cax=cax, **kwargs)colorbar(mappable, ax=ax, **kwargs)
注:只能在plt和fig(figure)上调用colorbar(),对于figure的子图对象(axes)则不行('AxesSubplot' object has no attribute 'colorbar')。colorbar()作用是为某个axes(plot)添加小彩条,必须知道的两个前提信息是:
由于axes对象不具备colorbar()方法,因此“为哪个axes添加colorbar的问题”只能通过切换“当前axes”来解决;通过imshow()或contourf()方法的绘制得到的一个颜色映射彩图或轮廓线图像,其具备了所需的cmap信息,于是将其作为colorbar()的首个mappable参数即可。特别地,在使用fig.colorbar()的调用方式的时候,必须传递此参数(First define a mappable such as an image (with imshow) or a contour set (with contourf)),但若使用plt.colorbar()的调用方式,除了使用内部维持的“当前axes”对象,还将使用“当前cmap”(“刚才绘图所使用的cmap设置”),因此无需再指定mappable参数(假设我们就是要使用“当前cmap”为“当前axes”绘制小彩条的话),要开始以及维持“当前cmap”,首先必须是通过譬如plt.imshow()或plt.contourf()的方式进行一次图像绘制的准备工作,因为imshow或contourf命令中包含了cmap参数信息,可以用于设置和更新“当前cmap”,而使用对象方法ax.imshow()或ax.contourf()则是无效的(其中ax为轴域axes对象,但是WHY?)
另外我们之前已经尝试过使用imshow()、bar()创建小彩条,但是完全不如colorbar()来得方便啊
参数说明:
mappable参数:The Image, ContourSet, etc.(见上)。仅仅使用这一个参数或干脆不使用时,我们可以看到默认绘制的colorbar的形状和位置,一个位于“当前axes”右侧的垂直且细长的小彩条(实际上是一个填充了颜色的axes对象,就像之前使用imshow()、bar()创建的那样,如果不理解,可以回去看一看具体的实现过程),如果我们希望将其放在左侧,或者其它任意位置处、以任意宽高比的长方形状呈现,则指定cax参数,cax参数指定小彩条填充的区域的边框,其为一个axes对象,我们知道通过axes()方法,可以设置任意位置,任意宽高比的长方形状的轴域对象,在没有指定该参数时,默认将在当前axes右侧创建一个新的axes对象用以绘制小彩条。
ax参数可以用于设置为小彩条预留的空间,实际上它是告诉函数我们要添加的小彩条适用于哪个axes或哪些axes,默认情况下,我们是为“当前axes”添加color bar,相应的预留空间也就是该axes右侧的一小块空间,假设我们多个子图都使用了相同的颜色映射,则只需要为其设置一个小彩条,可以指定axes为全部子图对象的序列,那么会自动为小彩条分配相适应于全部子图大小的空间,具体见实验部分。假设我们为子图1添加了color bar,但是指定ax=子图2,那么将在子图2的右侧为color bar预留空间,于是看起来就好象这个color bar是为子图2添加的一样。
use_gridspec参数:看不懂
其它参数(两类):
注:If mappable is a ContourSet, its extend kwarg is included automatically.
shrink参数提供了一个简单的方式用于控制color bar的尺寸,但若提供了cax参数,则shrink参数将被忽略,因为cax参数已经为绘制小彩条提供了指定位置、大小的axes容器,具有最高优先级。
上述axes属性有时候并不能准确控制color bar的位置、大小等,这时应手动设置用于绘制color bar的axes的位置大小(cax参数)
It is known that some vector graphics viewer (svg and pdf) renders white gaps between segments of the colorbar. This is due to bugs in the viewers not matplotlib. As a workaround the colorbar can be rendered with overlapping segments(你妹的):cbar = colorbar()cbar.solids.set_edgecolor("face")draw()
# mappable参数
n=20
data=np.random.rand(n,n)
fig,axes=plt.subplots(2,2)
cm=['Set1','summer','Blues','cool']
im=[]
for i,ax in enumerate(axes.flat):
if i==0: continue
im.append(ax.imshow(data,cmap=cm[i]))
#plt.colorbar(im)
plt.imshow(data,cmap='hot') # 在使用plt.colorbar()之前必须先执行譬如plt.imshow(),主要目的是开始及维持“当前cmap”,否则就必须调用:plt.colorbar(image)
plt.colorbar() # 添加小彩条
plt.sca(axes[1,0]) # 切换当前axes,该axes理应设置'Blues'的cmap
#plt.imshow(data,cmap='Blues') # 但是如果不执行譬如plt.imshow(),就不会更新“当前cmap”信息
plt.colorbar() # 结果造成使用'spring'的cmap为当前axes添加小彩条的错误
#fig.colorbar()
plt.sca(axes[0,0])
plt.colorbar()
# 使用fig.colorbar()的调用方式:
plt.sca(axes[0,1])
fig.colorbar(im[2]) # im[0]的cmap为'summer',im[1]的cmap为'Blues',im[2]的cmap为'cool',试着更改此参数并观察结果
# cax参数,自定义小彩条的位置、大小形状
data=np.random.rand(20,20)
im2=plt.imshow(data,cmap='Set3')
ax1=plt.gca()
ax2=plt.axes([0.2,1,.6,.03]) # 用于绘制小彩条的axes,可以设置任意位置及大小
plt.sca(ax1)
plt.colorbar(cax=ax2,orientation='horizontal') # 指定小彩条的位置、形状(设置axes容器),且水平方向
plt.colorbar(im2,shrink=0.5,) # 默认位置、形状的小彩条,shrink参数收缩尺寸至0.5倍
# ax参数,指定添加的小彩条适用于哪个或哪些image axes
n=2
fig,axes=plt.subplots(2,2)
im=[]
for i,ax in enumerate(axes.flat):
im.append(ax.imshow(np.random.rand(n,n),cmap='summer'))
plt.colorbar(im[3],ax=axes,fraction=0.2) # 将fraction修改为0.8观察结果,此时的“虚拟容器”不再只是单个axes大小,而是整个子图矩阵,fraction将调整colorbar axes即预留空间所占“虚拟容器”的大小比例
# 热成像
def f(x, y): # 抛物面:z = x^2/2p + y^2/2q (p与q同号)
return x*x+y*y
n = 10
x = np.linspace(-3, 3, 4 * n)
y = np.linspace(-3, 3, 3 * n)
X, Y = np.meshgrid(x, y)
Z=f(X, Y)
ax1=plt.subplot(121)
plt.imshow(Z, cmap='hot', origin='low')
plt.xticks([])
plt.yticks([])
ax2=plt.subplot(122,projection='3d')
ax2.plot_surface(X,Y,Z,cmap=plt.cm.hot)
plt.tight_layout(rect=(0,0,2,1.2))
plt.colorbar(ax=[ax1,ax2],shrink=.43)
函数原型:matplotlib.pyplot.scatter(x, y, s=None, c=None, marker=None, cmap=None, norm=None, vmin=None, vmax=None, alpha=None, linewidths=None, verts=None, edgecolors=None, *, data=None, **kwargs)
参数说明:
x,y参数:array_like, shape (n, ),输入数据,x代表点的x轴坐标,y代表点的y轴坐标,n表示点的个数
s参数:scalar or array_like, shape (n, ), optional,点的尺寸,单位为point,size in point^2,譬如3表示点的尺寸为3 point * 3 point,Default is rcParams['lines.markersize']^2.
c参数:color, sequence, or sequence of color, optional,用于描述点标记的颜色,可能的值为:
注意:如果要为所有点指定相同的RGB或RGBA,应使用形为(1,3)或(1,4)的二维数组;c参数缺省为None,在这种情况下,点标记的颜色由color, facecolor or facecolors决定,如果这些也没有指定或为None,则点的颜色 is determined by the next color of the Axes' current "shape and fill" color cycle. This cycle defaults to rcParams["axes.prop_cycle"](不明白).
marker参数:MarkerStyle, optional,标记样式。标记可以是类的实例,也可以是特定标记的文本速记。默认为“无”,在这种情况下,它采用rcparams[“scatter.marker”]="o"(圆点标记)。有关标记样式的详细信息,请参见markers。
cmap参数:Colormap, optional, default: None,Colormap实例或注册的颜色映射名称。只有当c参数是一个浮点数组时,才使用cmap。如果没有,则默认为rc image.cmap。
norm参数:Normalize, optional, default: None,颜色映射过程中的标准化操作,参见pcolor()
vmin,vmax参数:scalar, optional, default: None,参见pcolor()
alpha参数:scalar, optional, default: None,透明度设置
linewidths参数:scalar or array_like, optional, default: None,点标记的边线宽度,注意,默认的边线颜色(edge color)为点的face color。默认宽度为 rcParams lines.linewidth.
edgecolors参数:color or sequence of color, optional, default: 'face',点标记的边线颜色,可能的值为:
注意:对于未填充的点标记,其edgecolors关键字参数无效,且边线颜色内部强制为'face'
kwargs:其它关键字参数:Collection properties
n=200
plt.scatter(np.random.rand(n)*10,np.random.rand(n)*10,s=np.random.rand(n)*10,label='label 1')
n=100
plt.scatter(np.random.rand(n)*10,np.random.rand(n)*10,s=np.random.rand(n)*60,marker='x',label='label 2')
plt.legend(loc=(1.01,0.85)) # 或者plt.gca().legend(['label 1','label 2'])
函数原型:matplotlib.pyplot.errorbar(x, y, yerr=None, xerr=None, fmt='', ecolor=None, elinewidth=None, capsize=None, barsabove=False, lolims=False, uplims=False, xlolims=False, xuplims=False, errorevery=1, capthick=None, *, data=None, **kwargs)
参数说明:
x、y参数同plot(x,y)含义,yerr、xerr见bar();fmt参数同plot(),设置线条的颜色、点标记、线条类型;ecolor描述error line的颜色;elinewidth描述error line的宽度;capsize参数见bar();capthick参数是关键字参数markeredgewidth(点标记边线宽)的别名(为了向后兼容,如果给定了mew或markeredgewidth,那么它们将重写(over-ride)capthick。这在将来的版本中可能会改变);barsabove参数为True时,error line将绘制在plot(x,y,marker)所绘的图像上面,默认是在其下面;
lolims, uplims, xlolims, xuplims参数:uplims、lolims适用于yerr,xuplims、xlolims适用于xerr。uplims和lolims用于设置是否显示误差范围的上限以及是否显示误差的下限,可以是单个布尔值(适用全部),也可以是一个布尔序列或者0/1序列(逐一设置);
errorevery参数:譬如取值为5时,每5个点绘制一次误差线error line,默认为1(对每个点都绘制error line)
其它关键字参数(所有其它关键字参数都被传递给绘制marker标记的plot函数):
譬如以下代码将绘制有着绿色厚边线的大红方形标记:x,y,yerr = rand(3,10) errorbar(x, y, yerr, marker='s', mfc='red', mec='green', ms=20, mew=4)
其中mfc、mec、ms和mew是较长属性名markerfacecolor、markeredgecolor、markersize和markeredgewidth的别名。
当然了,描述marker点标记的属性不止这几种,见文档
注意:
除了上述参数外,此函数还可以采用data关键字参数。如果给定了这样的data参数,则以下参数将被data[<arg>]替换:'x'、'xerr'、'y'、'yerr'。这样的'data'必须能够通过data[<arg>](譬如data['colors'])的方式访问,并且支持语法:<arg> in data
plt.errorbar([1,2,3,4],[1,2,3,4],[1,0.5,2,1.5],fmt='ro',ecolor='b',uplims=[1,0]*2,lolims=[0,1]*2)
函数原型:matplotlib.pyplot.table(**kwargs)
Call signature:table(cellText=None, cellColours=None, cellLoc='right', colWidths=None, rowLabels=None, rowColours=None, rowLoc='left', colLabels=None, colColours=None, colLoc='center', loc='bottom', bbox=None)
参数说明:
cellText参数:形为(m,n)的一个二维数组,给出表格(m行n列)中的全部值类型数据(不含标签)
rowLabels参数:设置行标签,即行名称或字段名序列(长为m)
colLabels参数:设置列标签,即列名称或字段名序列(长为n)
cellColours参数:设置表格(指数据所在格子,不包括行列标签格子)背景色,必须是一个形如(m,n)的数组,即为每一个格子设置颜色 rowColours参数:设置行标签所在格子的背景色,长为m的序列
colColours参数:设置列标签所在格子的背景色,长为n的序列
cellLoc参数:表格(特指数据格子)中数据在格子中的位置,默认靠右
rowLoc参数:行标签所在格子中字段的位置设置,默认靠左
colLoc参数:列标签所在格子中字段的位置设置,默认居中
colWidths参数:表格(特指数据所在格子)列宽,只接受列表,长度(大于也合法)等于cellText的1轴长
loc参数:表格在axes轴域中的位置,默认值为'bottom',即axes底部,参数取值可参见legend()的loc参数(但好像只允许以下取值:{'best': 0, 'bottom': 17, 'bottom left': 12, 'bottom right': 13, 'center': 9, 'center left': 5, 'center right': 6, 'left': 15, 'lower center': 7, 'lower left': 3, 'lower right': 4, 'right': 14, 'top': 16, 'top left': 11, 'top right': 10, 'upper center': 8, 'upper left': 2, 'upper right': 1} ),譬如取值'best'
bbox参数:如何使用?
函数返回一个matplotlib.table.Table实例,cellText or cellColours参数都是必须被提供的,要实现对表格更精细的绘制,使用Table类,并调用Axes.add_table()方法将其添加到轴域(For finer grained control over tables, use the Table class and add it to the axes with add_table().But how to use?)
其它用于描述Table属性的关键字参数见文档
a=np.random.randint(5,25,12).reshape(4,3)
col_labels=['col'+str(i) for i in range(1,a.shape[1]+1)]
row_labels=['row'+str(i) for i in range(1,a.shape[0]+1)]
cmap=plt.get_cmap("tab20c")
plt.figure(figsize=(7,5))
t=plt.table(cellText=a,colLabels=col_labels,rowLabels=row_labels,loc='upper right',
colWidths=[0.05,0.1,0.15],cellColours=cmap(a))
for i in range(3):
plt.plot(a[i],marker='o',markersize=7,label='row'+str(i+1))
plt.xticks([0,1,2],['col1','col2','col3'])
plt.legend(loc='lower left')
A demo from document
在过去的5年、10年、20年、50年、100年中因霜冻、飓风、洪水、地震、冰雹造成的损失一览表:
# a demo from document
# 注:data中分别是:第一行为5年、第二行为10年、第三行为20年、第四行为50年、第五行为100年数据
data = [[ 66386, 174296, 75131, 577908, 32015],
[ 58230, 381139, 78045, 99308, 160454],
[ 89135, 80552, 152558, 497981, 603535],
[ 78415, 81858, 150656, 193263, 69638],
[139361, 331509, 343164, 781380, 52269]]
col_labels = ('Freeze', 'Wind', 'Flood', 'Quake', 'Hail')
row_labels = ['%d year' % x for x in (100, 50, 20, 10, 5)]
# start my practice
data=np.array(table_data)
colors=plt.cm.Reds(np.linspace(0,0.5,len(row_labels))) # len(row_labels)=5,对照Colormap Reference的Reds小彩条,0为起点,1为终点,0.5为中点,本语句作用就是在Reds小彩条起点到中点均匀取5次颜色采样
row_colors=colors[::-1] # 逆序
cell_data=[]
# 绘制柱状图
index=[(2*i+1)/10 for i in range(5)]
width=0.08
bottom=0
for i in range(len(data)):
plt.bar(index,data[i],width=width,bottom=bottom,color=colors[i])
for j in range(len(col_labels)):
plt.axhline(data[i][j]+(bottom if isinstance(bottom,np.ndarray) else [bottom]*len(col_labels))[j],0,(index[j]+width*0.27)/(plt.xlim()[-1]-plt.xlim()[0]),alpha=0.5,color=plt.cm.Set1(np.random.rand()),linestyle='--',linewidth=0.5)
bottom+=data[i]
cell_data.append(['%.1f'%(i/1000) for i in bottom])
cell_data=cell_data[::-1]
# 绘制表格
plt.table(cellText=cell_data,rowLabels=row_labels,colLabels=col_labels,rowColours=row_colors)
# others
plt.xticks([])
plt.yticks([500000,1000000,1500000,2000000,2500000],[500,1000,1500,2000,2500])
plt.ylabel("Loss in ${0}'s".format(1000))
plt.gcf().set_figwidth(10)
plt.gcf().set_figheight(6)
plt.title('Loss in disaster')
Call signatures:area(x,y1,[c1],y2,[c2],...) # 最简单的调用是绘制一条线段:area(x,y,[c])area(x,y1,[c1],...,linestyle='',areaColours=[...])# linestyle和areaColours为可选关键字参数area(x,y1,[c1],...,linestyle='',areaColours=[...],**kwargs) # kwargs参数设置Line2D等其它属性,全部传递给plot()
def detection(args):
'''检验area()位置参数是否合法,以及返回其中颜色参数对应的线条
索引,此为解析之结果。已知其应为:x,y,[c],[y2,[c2]],...
省略号表示前一项的无限重复。使用正则表达式:^x(yc?)+$
进行检验。函数返回三类值:如果参数合法,但没有设置颜色,则
返回None,否则返回颜色及其对应的线条索引;如果参数不合法,
则返回False
'''
import re
p=re.compile(r'^x(yc?)+$')
s=''.join(['x']+['c' if isinstance(i,str) else 'y' for i in args[1:]])
if not p.search(s):
return False
colors=[i for i in args if isinstance(i,str)]
if len(colors)==0:
return None
return [colors,[i for i,e in enumerate(s[1:].split('y')[1:]) if e]] # [颜色序列,颜色对应的线条索引序列]
'''(origin) function detection:
import re
p=re.compile(r'^x(yc?)+$')
s=['c' if isinstance(i,str) else 'y' for i in args[1:]]
s=['x']+s
s=''.join(s)
print(p.search(s))
r=s[1:].split('y')[1:]
index=[i for i,e in enumerate(r) if e]
print(index)
'''
def area(*args,**kwargs):
'''位置参数说明:
x: 线条基点的x轴坐标(基点:构成折线段的基本点)
y: 线条基点的y轴坐标
c: 线条的颜色
注1:以上参数勿以键值对形式传递,应严格以位置参数传递
注2:线条的颜色c参数是可选的
注3:构成面积图的折线一般具有多条,其x轴坐标一致,可以同时
给出多条折线的y轴坐标,args参数实际上允许是x和任意数量
的y,[c]组合,譬如x,y1,y2,c1,y3,c2,其中c1对应y2,c2
对应y3,未设置的y1颜色同areaColour(linestyle=''即可)
注4:位置参数args的合法性由detection函数验证,detection()
函数同时具有解析线条颜色参数设置的作用,即将颜色参数与
线条一一对应的作用
关键字参数说明:
areaColour: 接受一个颜色序列,描述平面坐标上某一线条与位于
其下方的另一条线条(或者说其在args中位于其前面的线条)
之间区域填充的颜色,对于最下方或者args中的第一条线条来
说,是其与x轴之间区域填充的颜色
其它关键字参数: 其它一切关键字参数都将传递给plt.plot()函数
,用于绘制线条
注5:对detection函数的说明:其具备存在的合理性,对参数列表
进行合法性检验以及解析,逻辑顺畅并无不妥之处,其次是检
验参数和允许传递line color也是后添加的,因此额外编写代
码实现
'''
args=list(args)
# detect the validity of args and interpret it:
ret=detection(args)
if ret==False:
print('参数非法!') # 可以在此处抛出异常
return 0
# 如果用户设置了linestyle,全部线条以此为准,如果没有,则默认linestyle=''
# ,即不进行连线,除非用户设置了某些线条的颜色,对这些线条,linestyle='-'
# 除了这些用户设置了颜色的线条外,其它全部线条仍linestyle=''
# 之所以默认不连接线条是为了美观,更重要的是无连接的必要,线条本身可以由不同
# 的区域填充颜色的轮廓显示出来,但是存在一类特殊情况,假设接连两个区域填充色
# 都是白色,且未设置线条颜色或设置linestyle,那么线条将彻底不可见,考虑到这
# 种情况,此时线条linestyle='-',其颜色由系统自定
if kwargs.get('linestyle'):
reset=False # 用户设置了linestyle,就不允许之后在对linestyle进行修改;
else:
reset=True # 否则,后面还可以重置linestyle,并且为了方便,先令全部linestyle=''
kwargs['linestyle']=''
# 截取填充区域的颜色设置:
noareas=True if kwargs.get('areaColour')==None else False
areaColors=kwargs.get('areaColour',plt.cm.Blues([0.1,0.3,0.5]))
if kwargs.get('areaColour'):
del kwargs['areaColour']
# prepare the lines to plot:
args=[i for i in args if not isinstance(i,str)]
xy_pack,line_pack=args[:2],[0,args[1]]
max_y=sum([max(i) for i in args[1:]])
for i in range(2,2+len(args[2:])):
xy_pack+=[args[0],args[i]+xy_pack[-1]]
line_pack+=[xy_pack[-1]]
# start plot the line,
plt.subplots()
lines=plt.plot(*xy_pack,**kwargs)
# and fill the area.
for i,e in enumerate(line_pack[1:],1):
plt.fill_between(args[0],e,line_pack[i-1],color=areaColors[i-1])
plt.axis([args[0][0],args[0][-1],0,max_y*1.2])
# set line color and reset line style for each one:
t=0
for i,line in enumerate(lines):
if ret!=None:
# 如果用户设置了线条颜色,则修改线条颜色:
if i in ret[1]:
line.set_color(ret[0][t])
t+=1
if reset: # 如果用户设置了当前线条的颜色并且允许重置linestyle,则置linestyle='-'
line.set_linestyle('-')
if not noareas: # 如果没有设置areaColours参数,则(否则存在一个FurtherWarning):
# 如果填充区域颜色为白色并且下一填充区域也为白色或者没有下一区域了,同时允许重置linestyle,则置linestyle='-'
if areaColors[i] in ['w','white'] and (areaColors[i+1] in ['w','white'] if i+1<len(lines) else True) and reset:
line.set_linestyle('-')
# 我真的是太长时间没有认真编程了,感觉生不如死,满脑袋浆糊了已经,太失败 19/01/17
# test
index=np.arange(6)
np.random.seed(3501)
d1=np.random.randint(2,12,6)
d2=np.random.randint(2,12,6)
d3=np.random.randint(2,12,6)
area(index,d1)
area(index,d1,d2,d3)
area(index,d1,d2,d3,areaColour=['green','w','red'])
area(index,d1,'red',d2,d3,'black',areaColour=['pink','w','w'],linestyle='--')
area(index,d1,d2,'red',d3,areaColour=['w','w','w'],marker='+',markersize=10)
其实就是线形图的极坐标表示,就此说一下polar()函数,函数本身很简单:
函数原型:matplotlib.pyplot.polar(*args, **kwargs)
all signature:polar(theta, r, **kwargs)
和plot()函数一样(意思是,将polar()当作plot()耍,除了plot()的x,y参数替换为theta,r之外,其余相同),支持多个theta, r参数组合,还有格式字符串fmt
之前咱们不是用极坐标绘制柱状图嘛,先用subplot(projection='polar')准备一个极坐标的画板,然后使用bar()绘制柱状图即可,跟在直角系下的区别也是,将bar()的x,height参数替换为theta,r,仅此而已。同样地,今天要绘制极坐标下的线形图,也可以先用subplot()准备个画板,然后用plot()直接绘制折线完事儿
其它设置刻度、刻度标记、legend什么的,就跟平时在直角系下一样一样的,坐标系就是一个画板,不影响实际的绘制工作
np.random.seed(0)
theta=np.linspace(0,2*np.pi,9)
r=np.random.rand(8)
r=np.append(r,r[0])
plt.polar(theta,r,'r:')
np.random.seed(0)
theta=np.linspace(0,2*np.pi,9)
r=np.random.rand(8)
r=np.append(r,r[0])
plt.subplot(projection='polar')
plt.plot(theta,r,'r:')
# 雷达图
label=['乐观','自信','悲观','自私','爱心']
n=len(label)
theta=np.linspace(0,2*np.pi,n+1)
r=np.random.rand(n) # r取值0-1
r=np.append(r,r[0])
plt.rcParams['font.sans-serif']=['SimHei'] # 使支持中文显示
plt.polar(theta,r,linestyle='')
labels_leida=plt.xticks(theta[:-1],label,fontsize=15,color='blue') # 此处似乎只能为全部标签设置同一颜色,现在要求为每一个label设置一种颜色
plt.ylim(0,1) # 因为r取值0-1,所以ylim(0,1),不做如此设置会导致出现重复轴标签,嗯,你自己尝试一下就知道了
#plt.thetagrids()
plt.fill_between(theta,r,color='gold')
plt.suptitle('muggledy的个人特征',x=0.5,y=1.1,color='red',fontsize=20)
plt.yticks(np.linspace(0,1,5),[]) # 不显示y轴即r轴标签,非禁用y轴刻度
# 为每一个label设置颜色,须知,xticks()返回的是一个二元列表,第一个元素是刻度序列,第二个元素是刻度标签序列,也就是我们要的对象(Text),在对象上调用set_color()即可:
labels_leida[1][0].set_color('red')
labels_leida[1][2].set_color('green')
labels_leida[1][3].set_color('gray')
labels_leida[1][4].set_color('purple')
函数原型:matplotlib.pyplot.hist(x, bins=None, range=None, density=None, weights=None, cumulative=False, bottom=None, histtype='bar', align='mid', orientation='vertical', rwidth=None, log=False, color=None, label=None, stacked=False, normed=None, *, data=None, **kwargs)
直方图由诸多紧密相连的bin(直译“箱子”)组成,每个bin为长方形的条状,其宽度总是表示样本落入的某一值区域范围(或称“组”group),高度可能表示落入此区域的样本数量(频数),也可能表示样本落入此区域的概率密度,具体表示谁得看density参数或normed参数的设置。
参数说明:
x:样本数据,可以包含多个样本集合,同一样本集合的bin颜色是相同的,不同样本集合的bin颜色不相同
bins:可以是标量、数值序列或字符串。单个标量表示bin的个数n,设全部样本的值范围为s,那么s将被均匀分配给这n个bin,即每个bin的宽度相同,且等于s/n。若想自定义每个bin的宽度,即不等间隔的直方图,则使用数值序列,这个序列中的元素为:[第一个bin的左端刻度,第一个bin的右端刻度,第二个bin的右端刻度,...,第n个bin的右端刻度](这个刻度序列总是作为hist()的第二个返回值返回),第n个bin的右端刻度~第一个bin的左端刻度即为全部样本的取值范围。如果使用Numpy 1.11或更新版本,还可以选择描述不同分箱策略的字符串值,例如'auto','sturges','fd','doane','scott','rice','sturges'或'sqrt',见numpy.histogram。
range:一个元组,指定样本的上下界(阈值),丢弃非此范围内的样本
density:默认为False。当其为True时,直方图的总面积为1,每个bin的高度表示“概率密度”(很容易理解,假设bin的宽度很小很小,我们用一个函数来对其进行拟合,由于总面积为1,即该函数上的积分值为1(分布函数),因此其表示的是“概率密度函数”,bin的高度相应的也就是概率密度了),每个bin的面积表示变量落在此间区域的概率。当density取值False时,bin的高度表示落入此间区域的样本频数,将全部bin的高度求和即得总样本容量(总样本个数)。该参数取代了旧版本的normed参数,目前两个参数可以任取其一进行设置,推荐使用density。
weights:为每一个样本设置权重,默认都相同。数组形状和x相同。An array of weights, of the same shape as x. Each value in x only contributes its associated weight towards the bin count (instead of 1). If normed or density is True, the weights are normalized, so that the integral of the density over the range remains 1.(此处不太明白)
cumulative:缺省为False,如果为True,则直方图中每个bin的高度为该bin所在区域样本频数加上较小值区域内的所有bin的全部样本频数之和。最后一个bin给出了样本的总数。如果normed或density参数也为True,则将直方图归一化,使得最后一个bin高度等于1,实际上若对此时的直方图进行拟合,得到的曲线就是“分布函数”。If cumulative evaluates to less than 0 (e.g., -1), the direction of accumulation is reversed. In this case, if normed and/or density is also True, then the histogram is normalized such that the first bin equals 1.(为什么会小于0?)
bottom:设置每个bin的底部基线,默认为0。为单个标量时,表示适用于全部bin
histtype:{'bar', 'barstacked', 'step', 'stepfilled'},要绘制的直方图的类型:
align:{'left', 'mid', 'right'},一般我们总是选择'mid',其亦为缺省值
orientation:{'horizontal', 'vertical'},如果取值'horizontal',那么barh()将被使用以绘制条形图(直方图本质就是条形图)
rwidth:直方图bin的宽度百分比,默认值为1,相邻bin之间紧密相连,没有空隙。假如我们取值0.5,则bin的宽度缩小为原来的一半,将导致相邻bin之间留有较大的空隙
color:单个颜色或颜色序列,必须与样本数据一一匹配,即有多少个数据集,就要设置多少个颜色配对(假如我们希望设置某一数据集颜色的话)
edgecolor:bin的边界颜色,如果不设置该值,则不同的bin之间没有明显的界限区分,当相邻两个bin的高度一致时,将会造成视觉干扰,所以一般都是要设置该参数的
log:设置对数刻度,默认为False
label:为每一个样本数据集设置标签(供legend()使用)
stacked:多个数据集时是否堆叠显示,允许与histtype参数同时使用,因为histtype为'step'时,多个数据集是重叠显示的线框图,当指定stacked取True时,多个数据集将变成以堆叠形式显示的线框图,当histtype取'bar'时,若stacked为True,则堆叠显示,即stacked优先级更高
normed:功能同density参数,推荐使用替代它的density
返回值:
直方图与条形图(柱状图)的区别:
首先,条形图是用条形的长度表示各类别频数的多少,其宽度(表示类别)则是固定的
直方图是用面积表示各组频数的多少,矩形的高度表示每一组的频数或频率,宽度则表示各组的组距,因此其高度与宽度均有意义
其次,由于分组数据具有连续性,直方图的各矩形通常是连续排列,而条形图则是分开排列
最后,条形图主要用于展示分类数据,而直方图则主要用于展示数据型数据
# 现在有一组数据,根据全班同学数学成绩绘制的直方图,数据是我自己随意捏造的,我们以10分作为一组group(一百分总共划分为10组),观察落入不同group的分布情况
data=[25,33,45,46,50,54,56,61,61,65,69,73,77,77,78,78,78,79,80,82,82,83,84,87,87,88,92,92,95]
bins=[i*10 for i in range(11)]
def cc(arg):
'''Shorthand to convert 'named' colors to rgba format at 60% opacity.'''
return mcolors.to_rgba(arg, alpha=0.6)
color=cc('pink')
plt.hist(data,bins,edgecolor='red',color=color,rwidth=1,) # 此时图中bin的高度是(成绩)样本的频数,即分数落在某一group(分值区域)的人数。由于普遍规律是(较大样本下):
# 学生的成绩服从正态分布,因此当取density为True时,直方图应该能够很好地拟合出服从(mu,sigma)的正态概率密度函数,当然了,肉眼直接看就能看出大概情况,中间高两头低嘛
plt.xticks(bins,bins)
plt.annotate('人数',(-2,7.5),fontsize=12)
plt.annotate('分值',(101,0.5),fontsize=12)
np.random.seed(20190123)
data=np.vstack([np.random.rand(10),np.random.rand(10)])
plt.hist(list(data),5,density=False,edgecolor='k',color=[mcolors.to_rgba('red', alpha=0.1),'purple'],label=['hist1','hist2'],histtype='step') #
plt.legend()
待求一组随机样本X,满足:$X\sim N(\mu,\sigma)$
根据标准化:$\frac{X-\mu}{\sigma}\sim N(0,1)$
设:$Z=\frac{X-\mu}{\sigma}$,即有:$Z\sim N(0,1)$,$X=\sigma Z+\mu\sim N(\mu,\sigma)$
又知np.random.randn(n)可以生成指定数量n的一组随机样本,其符合标准正态分布($Z$),于是有:
$\sigma *np.random.randn(n)+\mu\sim N(\mu,\sigma)$
# 产生一组符合正态分布(mu,sigma)的样本,并对其拟合
mu=4
sigma=2
x=np.random.randn(10000)*sigma+mu # 样本要足够大,才能显示出其遵循的分布规律
n,bins,_=plt.hist(x,50,density=True,color='g',edgecolor='k') # 此时bin高度为概率密度
plt.title('$x\sim N(\mu,\sigma),\mu=4,\sigma=2$')
# add a 'best fit' line:
y=scipy.stats.norm.pdf(bins,mu,sigma)
plt.plot(bins,y)
The documentation tells us about matplotlib.mlab.normpdf, and do not use this function any more, use scipy.stats.norm.pdf instead.
Hence a previous code like:
import matplotlib.mlab as mlab
import numpy as np
x = np.linspace(-3,3)
mu = 0
sigma = 1
y = mlab.normpdf(x, mu, sigma)
should now read:
import numpy as np
import scipy.stats
x = np.linspace(-3,3)
mu = 0
sigma = 1
y = scipy.stats.norm.pdf(x, mu, sigma)
原型:matplotlib.pyplot.contour(*args, data=None, **kwargs)
Call signature:contour([X, Y,] Z, [levels], **kwargs)
另外还有contourf()函数,它和contour()的使用一模一样(对同一图像,它们的参数调用应该是一致的),两者分别绘制填充颜色的等高线图以及等高线图X和Y都必须是二维的,同Z的形状,一般它从meshgrid()产生,这意味着我们所绘的是一个二元函数,Z=f(X,Y)。levels可以是整数也可以是一维数组,如果是整数(n),表示等高线的数量(n+1,有n个均匀间隔),如果是数组(元素是递增的),表示等高线的位置(这个描述几乎不能理解,实际上等高线是有数值的,就是某些处于同一高度的点(x,y)所构成的一条连续曲线(想象拿一个锋利的平面去切割一座山,得到的切面轮廓线),譬如当你指定levels的值为[3,6],这意味着只绘制两条等高线,两条线的高度分别为3和6),其他参数(譬如颜色、透明度、色域、线条属性等)交给kwargs,见文档。下面看一下具体使用:
# y = x^2 – 2*x*y + 3*y^2 + 2*x – 2*y
x=np.linspace(-10,10,40)
y=np.linspace(-5,5,20)
X,Y=np.meshgrid(x,y)
Z=X**2-2*X*Y+3*Y*Y+2*X-2*Y
# 绘制填充颜色的等高线图
plt.contourf(X, Y, Z, 15, cmap = plt.cm.hot)
plt.colorbar()
# 绘制等高线,当图形中只使用一种颜色的时候,会使用虚线来表示负数,实线表示正数
C = plt.contour(X, Y, Z, 15, colors = 'black')
# 显示各等高线的数据标签
plt.clabel(C, inline = True, fontsize = 8)
#%matplotlib notebook
fig = plt.figure()
ax = fig.gca(projection='3d')
ax.plot_surface(X, Y, Z, cmap = plt.cm.hot)
最简单的就是极坐标的那种了,但是太胖了点,下面是我搜到的其他的画法,纯粹凑个热闹,都可化显函数作图,下面两个我不是很满意,如果有兴趣,可以使用贝塞尔方程绘制心形线,参见"patches与path.ipynb"#心形线
$f(x)=-tan(\sqrt[2]{1-|x|^\frac{3}{2}})+\frac{\pi}{2}$
$g(x)=\sqrt[2]{\frac{1}{4}-(x+\frac{1}{2})^2}+\frac{\pi}{2}$
$h(x)=\sqrt[2]{\frac{1}{4}-(x-\frac{1}{2})^2}+\frac{\pi}{2}$
x=np.linspace(-1,0,100)
y=np.sqrt(np.fabs(0.25-np.power(x+0.5,2)))+0.5*np.pi
plt.plot(x,y)
x=np.linspace(0,1,100)
y=np.sqrt(np.fabs(0.25-np.power(x-0.5,2)))+0.5*np.pi
plt.plot(x,y)
x=np.linspace(-1,1,100)
y=0.5*np.pi-np.tan(np.sqrt(np.fabs(1-np.power(np.fabs(x),1.5))))
plt.plot(x,y)
plt.annotate('g(x)',(-0.5,1.9))
plt.annotate('h(x)',(0.5,1.9))
plt.annotate('f(x)',(0.25,0.4))
$x^2+(y-\sqrt[3]{x^2})^2=1$
化为参数方程:
$\begin{cases} x=sin(t) \\ y-\sqrt[3]{x^2}=cos(t) \end{cases}$
t=np.linspace(0,np.pi,100)
x=np.sin(t)
y=np.cos(t)+np.power(x,2.0/3)
plt.plot(x,y)
plt.plot(-x,y)
极坐标:$p=a\theta$
a=2 # 取a为2
theta=np.linspace(0,4*np.pi,100)
p=a*theta
plt.polar(theta,p)
以线形图为例,无非就是画点、连线,一气呵成,要实时动态地绘制线形图,就是将n个点的一次性连接拆分成n-1次两点的连线(当然了你也可以每次连接更多个点),本来n个点的连接,用一个plot()就完事,现在需要n-1次plot(),每次需要知道的就是起点和终点的位置坐标,然后连起来,起点是上一次plot()的终点,所以我们要做的就是产生下一次的点的位置,就是需要一个不断产生图像在前进方向轨迹上的点的坐标数据的生成器
见./matplotlib/DB/demo/jupyter中交互式动图展示.ipynb 和 交互式动图脚本(一元函数).py
def g_points(fun,start,end,accuracy=30,n=5):
'''
功能:一元显函数轨迹点坐标生成器
参数说明:fun: 函数关系,譬如一个lambda表达式
start: x轴起点
end: x轴终点(start和end是函数f自变量x的取值范围,闭区间)
accuracy: 精细程度,单位长度内所绘点的个数,一个大于等于1的正整数,控制线形图的光滑度
n: 一次plot绘制的点的个数,一个大于1的正整数(适当调高accuracy和调小n可以延长动画)
'''
n=int(np.fabs(n))
if n==1: return
accuracy=int(np.fabs(accuracy))
if accuracy==0: return
counts=int((end-start)*accuracy+1)
x=np.linspace(start,end,counts)
t=0
while True:
try:
x[t]
except:
break
yield [x[t:t+n],fun(x[t:t+n])]
t+=(n-1)
for x,y in g_points(lambda x:np.sin(x),0,4*np.pi,accuracy=5):
plt.plot(x,y)
plt.pause(0.001) # Pause for interval seconds.
使用animation模块绘制动态图,见./matplotlib之animation.ipynb
如果创建了许多个图像(figure),你需要知道一个事实:除非使用close()方法显式地关闭,否则图像所占用的内存是不会被释放的。通过删除对对象的(外部)引用或者使用窗口管理器关闭屏幕上显示图形的窗口都不足以使得内存被释放,因为直至close()被调用,pyplot模块内部将会始终保持对图像的内部引用。
Here are many frequently asked questions, you may really benefit from it.
pyplot分别提供了函数式编程和面向对象编程的接口api,可以说,这是两种编程风格俱不可磨灭的最佳印证。函数式表达简洁(就像是在敲命令)但是过程稍微有点不清晰,对于初学者,有可能困惑于正在操作的figure或plot是谁以及如何在不同的figure和plot之间自由切换的问题,可见其灵活性也大打折扣。对象式操作过程明晰但是写出来的代码相较于函数式显得冗长,需要不断返回待操作的对象以及为其命名(还得抓脑袋想出个有意义的名字)。推荐以MATLAB风格为主绘图,辅以面向对象。官方明确表示:面向对象更适合于“复杂”绘图(The object-oriented API is recommended for more complex plots.),但要想真正学透彻matplotlib,必须深入面向对象。(另外还存在第三种方式,导入pylab模块,明确不推荐)
jupyter notebook或ipython中默认都是交互式绘图,在python脚本中,你需要手动开启,使用plt.ion()和plt.ioff()开启和关闭interactive mode(交互模式)。两者的区别在于,执行图像绘制命令如plot()之后图像是否显示,以及当图像显示之后能否动态实时地修改。非交互模式必须使用plt.show()才能显示图像,且后续无法修改,只能推倒重新来过。
中文显示成小方格,修改配置即可
解决方案:
plt.rcParams['font.sans-serif']=['SimHei'] # for Chinese charactersplt.rcParams['axes.unicode_minus']=False # 解决负号'-'显示为方块的问题myfont=matplotlib.font_manager.FontProperties(fname='.../SimHei.ttf') # 字体下载plt.title('函数图像',fontproperties=myfont,fontsize=32)mpl-data文件夹内(执行 matplotlib.matplotlib_fname() 将会获得配置文件的全路径)font.family : sans-seriffont.sans-serif : SimHei, Bitstream Vera Sans, Lucida Grande, Verdana, Geneva, Lucid, Arial, Helvetica, Avant Garde, sans-serifmpl-data/fonts/ttf文件夹下即可推荐使用动态设置
muggledy 2019/1/8~2019/1/20 初级教程基本整理完毕 1.0