目录
一、对Matplotlib图形结构的认识
二、Matplotlib绘图设置主要方法
1、Matplotlib绘制普通折线图
(1) 设置折现颜色、形状、折点样式
(2) 设置图片大小并保存
(3) 绘制x轴和y轴的刻度
(4) 中文正常显示设置
(5) 一图多线
(6)标出图中某些特定点
(7)移动坐标轴的位置
2、绘制散点图
3、绘制条形图(竖)
4、绘制条形图(横)
5、绘制条形图(并列)
6、绘制条形图(堆积)
7、绘制饼图
8、直方图
9、散点图
10、不同坐标轴(极坐标、对数坐标)
11、一图多个子图
三、用Matplotlib绘图总结
Matplotlib是一个Python2D绘图库,它可用于Python脚本、Python和IPython shell、JupyterNotebook、Web应用程序服务器和四个图形用户界面工具包。
Matplotlib绘图非常方便,只需几行代码即可生成直方图、饼图、散点图等常见图形。
本文主要总结了Matplotlib绘图中的一些常用方法,把用Matplotlib绘制常见统计图做一个汇总,解决了中文字符无法正常显示问题,并可以根据需要一张图显示不同字体。
一、对Matplotlib图形结构的认识
通常,可将一张Matplotlib图像分成三层结构:
第一层:底层容器曾,主要包括Canvas、Figure、Axes;
第二层:辅助显示层,主要包括axis、spines、grid、legend、title等;
第三层:图像层,即通过plot、scatter等方法绘制的图像。
二、Matplotlib绘图设置主要方法
1、Matplotlib绘制普通折线图
使用默认设置生成的折线图,缺乏美感。下面就来一步步的美化。
说一下,可以不加%matplotlib inline 这一句,如果不加这一句,只是首次启动jupyternotebook需要运行两次才会显示出图像,后面都正常。
from matplotlib import pyplot as plt
%matplotlib inline
x = range(1,8) # x轴的位置
y = [17, 17, 18, 15, 11, 11, 13]
plt.plot(x,y)
plt.show()
(1) 设置折现颜色、形状、折点样式
x = range(1,8) # x轴的位置
y = [17, 17, 18, 15, 11, 11, 13]
plt.plot(x,y,color='red',alpha=0.5,linewidth=3,linestyle=':',marker='*',markersize='20',markeredgecolor='g',markeredgewidth = 2)
plt.show()
color=‘red’:折线颜色
alpha=0.5:折线透明度(0-1)
linewidth=3:折线宽度
linestyle=’:’:折线线的样式
marker=’*’:折点样式
markersize=‘20’:折点大小
markeredgecolor=‘g’:折点边缘颜色
markeredgewidth = 2:折点边缘线宽度
(2) 设置图片大小并保存
from matplotlib import pyplot as plt
import random
x = range(2,28,2)
y = [random.randint(15,30) for i in x]
#设置图片大小
plt.figure(figsize=(20,8),dpi=80)
plt.plot(x,y)
#plt.show()
#保存图片
plt.savefig('./t1.png')
figsize:指定figure的宽和高,单位为英寸;
dpi:图画的分辨率,缺省值为80
注意:保存要放在绘制的下面,并且plt.show()会释放figure资源,如果在plt.show()之后保存图片,将只能保存空图片。
图片也可以保存成svg这种矢量图格式,这种矢量图在网页中放大后不会有锯齿。
(3) 绘制x轴和y轴的刻度
坐标轴刻度不用x、y的默认值,可用plt.xticks()、plt.yticks()来设置,其中rotation=45是让文字旋转45度
from matplotlib import pyplot as plt
import random
x = range(2,15,2)
y = [random.randint(15,30) for i in x]
#设置图片大小
plt.figure(figsize=(10,8),dpi=80)
#构造x轴刻度标签
x_ticks_label = ['{};00'.format(i) for i in x]
plt.xticks(x,x_ticks_label,rotation = 45)
#设置y轴刻度标签
y_ticks_label = ['{}℃'.format(i) for i in range(min(y),max(y)+1)]
plt.yticks(range(min(y),max(y)+1),y_ticks_label)
#绘图
plt.plot(x,y)
plt.show()
(4) 中文正常显示设置
matplotlib只显示英文,中文显示为‘口’,网上常见的设置方法都过于复杂,比较实用的一种方法是
plt.rcParams[‘font.sans-serif’]=[‘SimHei’] # 用来正常显示中文标签
plt.rcParams[‘axes.unicode_minus’]=False # 用来正常显示负号
但是这种设置出的中文通篇都是一种字体,无法个性化设置,比如标题一种字体,轴坐标一种字体。
我的方法可以设置多个字体、字号,只需要过matplotlib下的font_manager就可以解决。
首先通过路径“C:\Windows\Fonts\”查看自己Windows下的字体。
再通过font_manager.FontProperties()设置字体属性:
my_font = font_manager.FontProperties(fname=‘C:\Windows\Fonts\msyh.ttc’,size=20)
最后,设置坐标轴刻度的fontproperties属性:plt.xticks(x,fontproperties=my_font)
import matplotlib.pyplot as plt
import random
from matplotlib import font_manager
my_font = font_manager.FontProperties(fname='C:\Windows\Fonts\msyh.ttc',size=20)
my_font1 = font_manager.FontProperties(fname='C:\Windows\Fonts\STCAIYUN.TTF',size=25)
x = range(2,14,2)
y = [random.randint(15,30) for i in x]
plt.figure(figsize=(8,4),dpi=80)
#设置X轴的刻度
x_ticks_label = ['2月{}日'.format(i) for i in x]
plt.xticks(x,x_ticks_label,fontproperties=my_font)
#设置Y轴的刻度
y_ticks_label = ['{}℃'.format(i) for i in range(min(y),max(y)+1)]
plt.yticks(range(min(y),max(y)+1,2),y_ticks_label,size=20)
plt.plot(x,y,marker='o')
plt.title('近10天最高温度',fontproperties = my_font1)
plt.show()
(5) 一图多线
通过使用多次plt.plot()达到一图多线目的:
plt.plot(x,y1,label=‘我’)
plt.plot(x,y2,label=‘同事’)
添加图例用plt.lengend()
注意:只有在图例里添加prop参数是显示中文,其他都是用fontproperties参数。loc:设置位置,有upper left、lower left、center left、upper center
import matplotlib.pyplot as plt
from matplotlib import font_manager
import random
my_font = font_manager.FontProperties(fname='C:\Windows\Fonts\msyh.ttc',size=20)
x = range(11,31)
y1 = [random.randint(0,8) for i in x]
y2 = [random.randint(0,8) for i in x]
plt.figure(figsize=(10,5),dpi=80)
plt.plot(x,y1,label='我')
plt.plot(x,y2,label='同事')
x_ticks_label = ['{}岁'.format(i) for i in range(11,32,2)]
y_ticks_label = ['{}个'.format(i) for i in range(min(y1),max(y1)+2,2)]
plt.xticks(range(min(x),max(x)+2,2),x_ticks_label,fontproperties=my_font)
plt.yticks(range(min(y1),max(y1)+2,2),y_ticks_label,fontproperties=my_font)
plt.xlabel('年龄',fontproperties=my_font)
plt.ylabel('好友数',fontproperties=my_font)
plt.legend(prop=my_font,loc='upper right')
plt.show()
(6)标出图中某些特定点
import matplotlib.pyplot as plt
import numpy as np
#为正常显示中文字体,添加的代码
plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus']=False
x = np.arange(-10,10,0.1)
plt.plot(x,x**2,'r.-',label='y=x**2')
plt.annotate("Important value", (0,0), xycoords='data',
xytext=(8, 38),
arrowprops=dict(arrowstyle='->'))
plt.title("测试一些函数")
plt.legend() #显示图例
plt.xlabel('x value')
plt.ylabel('y value')
plt.show()
import matplotlib.pyplot as plt
import numpy as np
x1 = np.random.normal(30, 3, 100)
x2 = np.random.normal(20, 2, 100)
x3 = np.random.normal(10, 3, 100)
plt.plot(x1, label='plot')
plt.plot(x2, label='2nd plot')
plt.plot(x3, label='last plot')
#生成图例框
plt.legend(bbox_to_anchor=(0., 1.02, 1., .102), loc=1,
ncol=3, mode="expand", borderaxespad=0.)
plt.annotate("Important value", (45,20), xycoords='data',
xytext=(5, 38),
arrowprops=dict(arrowstyle='->'))
plt.show()
x = np.arange(0, 20, 0.01)
plt.plot(x, x**2)
#为正常显示中文字体,添加的代码
plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus']=False
#增加x、y轴文字说明
plt.xlabel("Money Earned",color='r',fontsize=20)
plt.ylabel("Consume Level")
#增加标题
plt.title("测试一些函数")
#图内文字,指定首字出现的x轴,y轴,文字本身
plt.text(2.5,100,"图内文字测试")
#箭头指示,指定文字,箭头指向的坐标,文字显示的坐标,箭头的属性
plt.annotate('最大值', xy=(20, 400), xytext=(12.5, 400),
arrowprops=dict(facecolor='black', shrink=0.05),
)
plt.grid(True) # 设置网格线
plt.show()
(7)移动坐标轴的位置
import matplotlib.pyplot as plt
import numpy as np
x = np.arange(-10,10,0.1)
#获得当前图表的图像
ax = plt.gca()
#设置图形的包围线
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')
ax.spines['bottom'].set_color('blue')
ax.spines['left'].set_color('r')
#设置底边的移动范围,移动到y轴的0位置
#‘data’:移动轴的位置到交叉轴的指定坐标
ax.spines['bottom'].set_position(('data',0))
ax.spines['left'].set_position(('data',0))
plt.plot(x,x**3,'g',label='y=x**3')
plt.legend() #显示图例
plt.show()
2、绘制散点图
import matplotlib.pyplot as plt
from matplotlib import font_manager
import random
my_font = font_manager.FontProperties(fname='C:\Windows\Fonts\msyh.ttc',size = 18)
x = range(1,32)
y = [random.randint(11,26) for i in x]
plt.figure(figsize=(20,8),dpi=80)
plt.scatter(x,y,label='3月份温度',s=65,c='g')
x_ticks_label = ['{}日'.format(i) for i in x]
y_ticks_label = ['{}℃'.format(i) for i in range(min(y),max(y)+2,2)]
plt.xticks(x,x_ticks_label,fontproperties=my_font,rotation = 45)
plt.yticks(range(min(y),max(y)+2,2),y_ticks_label,fontproperties=my_font)
plt.title('3月份每日最高气温',fontproperties=my_font,size = 28)
plt.xlabel('月份',fontproperties=my_font,size = 23)
plt.ylabel('温度',fontproperties=my_font,size = 23)
plt.legend(prop=my_font)
plt.grid(alpha=0.5)
plt.show()
3、绘制条形图(竖)
import matplotlib.pyplot as plt
from matplotlib import font_manager
my_font = font_manager.FontProperties(fname='C:\Windows\Fonts\msyh.ttc',size = 20)
a = ['流浪地球','疯狂的外星人','飞驰人生','大黄蜂','熊出没·原始时代','新喜剧之王']
b = ['38.13','19.85','14.89','11.36','6.47','5.93']
plt.figure(figsize=(20,8),dpi = 80)
#绘制条形图
rects = plt.bar(range(len(a)),[float(i) for i in b],width=0.3,color=['r','g','b','r','g','b'],label='票房')
plt.xticks(range(len(a)),a,fontproperties=my_font)
plt.yticks(range(0,41,5),range(0,41,5),fontproperties=my_font)
#在条形图上加标注(水平居中)
for rect in rects:
height = rect.get_height()
plt.text(rect.get_x()+rect.get_width()/2,height+0.3,str(height),ha='center',size=20)
plt.title('2019年内地票房排名',fontproperties=my_font,size = 28)
plt.legend(prop=my_font)
plt.show()
4、绘制条形图(横)
from matplotlib import pyplot as plt
from matplotlib import font_manager
my_font = font_manager.FontProperties(fname='C:\Windows\Fonts\msyh.ttc',size=20)
a = ['流浪地球','疯狂的外星人','飞驰人生','大黄蜂','熊出没·原始时代','新喜剧之王']
b = ['38.13','19.85','14.89','11.36','6.47','5.93']
plt.figure(figsize=(20,8),dpi = 80)
rects = plt.barh(range(len(a)),[float(i) for i in b],height=0.5,color=['r','g','b','r','g','b'],label='票房')
plt.yticks(range(len(a)),a,fontproperties=my_font)
plt.xticks(range(0,41,5),range(0,41,5),fontproperties=my_font)
for rect in rects:
width = rect.get_width()
plt.text(width,rect.get_y()+0.5/2,str(width),fontproperties=my_font,va='center')
plt.show()
5、绘制条形图(并列)
import matplotlib.pyplot as plt
import numpy as np
index = np.arange(4)
BJ = [50,55,53,60]
Sh = [44,66,55,41]
rects1 = plt.bar(index,BJ,width=0.3)
rects2 = plt.bar(index+0.3,Sh,width=0.3,color='g')
plt.xticks(index+0.3/2,index)
for rect1 in rects1:
height = rect1.get_height()
plt.text(rect1.get_x()+rect1.get_width()/2,height+0.3,str(height),ha='center')
for rect2 in rects2:
height = rect2.get_height()
plt.text(rect2.get_x()+rect2.get_width()/2,height+0.3,str(height),ha='center')
plt.show()
6、绘制条形图(堆积)
import matplotlib.pyplot as plt
import numpy as np
index = np.arange(4)
BJ = [50,55,53,60]
Sh = [44,66,55,41]
rect1 = plt.bar(index,BJ,width=0.3,label='BJ')
rect2 = plt.bar(index,Sh,bottom=BJ,width=0.3,label='Sh')
plt.xticks(index,index)
for rect1 in rects1:
height = rect1.get_height()
plt.text(rect1.get_x()+rect1.get_width()/2,height/2,str(height),ha='center')
for rect2 in rects2:
height = rect2.get_height()
plt.text(rect2.get_x()-rect2.get_width()/2,height+min(BJ)-25,str(height),ha='center')
plt.legend()
plt.show()
7、绘制饼图
import matplotlib.pyplot as plt
from matplotlib import font_manager
#fname代表字体路径(本电脑中的字体路径,下载字体文件)
my_font = font_manager.FontProperties(fname='C:\Windows\Fonts\msyh.ttc',size=10)
label_list = ['Frogs','Hogs','Dogs','Logs']
size = [15,30,45,10]
color = ['blue','yellow','green','red']
explode = [0,0.1,0,0]
plt.figure(figsize=(10,8),dpi = 80)
patches,l_text,p_text = plt.pie(size,
explode=explode,
colors=color,
labels=label_list,
labeldistance=1.1,
autopct='%1.1f%%',
shadow=True,
startangle=90,
pctdistance=0.6)
for t in l_text:
t.set_fontproperties(my_font)
for t in p_text:
t.set_size(18)
plt.legend(prop=my_font)
plt.show()
8、直方图
import matplotlib.pyplot as plt
#标准正态分布又称为μ分布,是以均数μ=0、标准差σ=1的正态分布,记为N(0,1)
mu, sigma = 0,1
x = np.random.normal(mu,sigma,10000)
n, bins, patches = plt.hist(x,bins=100,facecolor='g', alpha=0.75)
plt.text(-3, 250, r'$\mu=0,\ \sigma=1$')
plt.grid(True)
plt.show()
9、散点图
import matplotlib.pyplot as plt
import random
x = np.random.normal(0, 1, 1000) # 1000个点的x坐标
y = np.random.normal(0, 1, 1000) # 1000个点的y坐标
c = np.random.rand(1000) #1000个颜色
s = np.random.rand(100)*100 #100种大小
plt.scatter(x, y, c=c, s=s,alpha=0.5)
plt.grid(True)
plt.show()
10、不同坐标轴(极坐标、对数坐标)
from matplotlib.ticker import NullFormatter
np.random.seed(19680801)
y = np.random.normal(loc=0.5, scale=0.4, size=1000)
y = y[(y > 0) & (y < 1)]
y.sort()
x = np.arange(len(y))
plt.figure(1)
# linear
plt.subplot(221)
plt.plot(x, y)
plt.yscale('linear')
plt.title('linear')
plt.grid(True)
# log
plt.subplot(222)
plt.plot(x, y)
plt.yscale('log')
plt.title('log')
plt.grid(True)
# symmetric log
plt.subplot(223)
plt.plot(x, y - y.mean())
plt.yscale('symlog', linthreshy=0.01)
plt.title('symlog')
plt.grid(True)
# logit
plt.subplot(224)
plt.plot(x, y)
plt.yscale('logit')
plt.title('logit')
plt.grid(True)
plt.gca().yaxis.set_minor_formatter(NullFormatter())
plt.subplots_adjust(top=0.92, bottom=0.08, left=0.10, right=0.95, hspace=0.25, wspace=0.35)
plt.show()
11、一图多个子图
用add_subplot方法给figure新增子图.
import matplotlib.pyplot as plt
import numpy as np
x = np.arange(1,100)
#新建figure对象
fig = plt.figure(figsize=(20,10),dpi=80)
#新建子图1
ax1 = fig.add_subplot(2,2,1)
ax1.plot(x,x)
#新建子图2
ax2 = fig.add_subplot(2,2,2)
ax2.plot(x,x**2)
ax2.grid(color='r',linestyle='--',linewidth=1,alpha=0.3)
#新建子图3
ax3 = fig.add_subplot(2,2,3)
ax3.plot(x,np.log(x))
plt.show()
三、用Matplotlib绘图总结