对于matplotlib 而言,
- 首先需要创建一个画布【即 plt.figure()】
- 然后才可以进行各种图标绘制
- 最后通过【plt.show()】显示
- 【优雅】matplotlib 常见图:https://viatorsun.blog.csdn.net/article/details/118862476
- 【优雅】matplotlib 3D图:https://viatorsun.blog.csdn.net/article/details/118864728
文章目录
0、图表基本信息
import matplotlib.pyplot as plt
import numpy as np
import random
plt.figure(figsize=(8, 5)) # 新建空画布,并设置尺寸
plt.legend() # 显示图例
plt.title("我是中文标题") # 标题
plt.style.context(style): # 设置图表风格
plt.rcParams['font.family'] = ['Microsoft YaHei'] # 指定字体,默认不支持中文显示
plt.xlabel('我是X轴') # 坐标轴文本设置
plt.ylabel('我是Y轴')
plt.xticks(x_location+0.15, cate) # 为X轴设置刻度值
plt.yticks(y_location+0.15, cate)
plt.subplots() 解释
fig,ax = plt.subplots()
等价于:
fig = plt.figure()
ax = fig.add_subplot(1,1,1)
fig, ax = plt.subplots(1,3)
其中参数1和3分别代表子图的行数和列数,一共有 1x3 个子图像。函数返回一个figure图像和子图ax的array列表。
1、多子图 plt.subplot()
可以通过 plt.subplot() 展示多子图,也可以在画布上添加子图 fig.add_subplot()
for i in range(1, 7):
plt.subplot(2, 3, i)
plt.text(0.5, 0.5, str((2, 3, i)), fontsize=18, ha='center')
fig = plot.figure()
fig.subplots_adjust(hspace=0.4, wspace=0.4)
for i in range(1, 7):
ax = fig.add_subplot(2, 3, i)
ax.text(0.5, 0.5, str((2, 3, i)), fontsize=18, ha='center')
复杂排列方式 plt.GridSpec()
grid = plt.GridSpec(2, 3, wspace=0.4, hspace=0.3)
plt.subplot(grid[0, 0])
plt.subplot(grid[0, 1:])
plt.subplot(grid[1, :2])
plt.subplot(grid[1, 2]);
# 创建一些正态分布数据
mean = [0, 0]
cov = [[1, 1], [1, 2]]
x, y = np.random.multivariate_normal(mean, cov, 3000).T
# 设置坐标轴和网格配置方式
fig = plot.figure(figsize=(6, 6))
grid = plt.GridSpec(4, 4, hspace=0.2, wspace=0.2)
main_ax = fig.add_subplot(grid[:-1, 1:])
y_hist = fig.add_subplot(grid[:-1, 0], xticklabels=[], sharey=main_ax)
x_hist = fig.add_subplot(grid[-1, 1:], yticklabels=[], sharex=main_ax)
# 柱坐标轴画散点图
main_ax.plot(x, y, 'ok', markersize=3, alpha=0.2)
# 次坐标轴画频次直方图
x_hist.hist(x, 40, histtype='stepfilled', orientation='vertical', color='gray')
x_hist.invert_yaxis()
y_hist.hist(y, 40, histtype='stepfilled', orientation='horizontal', color='gray')
y_hist.invert_xaxis()
2、折线图 plt.plot()
x = np.linspace(-10, 10, 1000)
plt.figure(figsize=(8, 5)) # 新建空画布并设置尺寸
plt.plot(x, np.sin(x), ':r' , label='sin(x)')
plt.plot(x, np.cos(x), '-.g', label='cos(x)')
plt.legend() # 显示图例
plt.title("我是中文标题")
plt.ylabel('我是Y轴')
plt.show()
3、直方图 plt.hist()
import matplotlib.pyplot as plt
import numpy as np
from matplotlib import colors
from matplotlib.ticker import PercentFormatter
N_points = 100000
n_bins = 20
# Generate a normal distribution, center at x=0 and y=5
x = np.random.randn(N_points)
y = .4 * x + np.random.randn(100000) + 5
fig, axs = plt.subplots(1, 2, sharey=True, tight_layout=True)
# We can set the number of bins with the `bins` kwarg
axs[0].hist(x, bins=n_bins)
axs[1].hist(y, bins=n_bins)
plt.show()
3.1 二维直方图
要绘制二维直方图,只需两个长度相同的向量,对应于直方图的每个轴。
fig, ax = plt.subplots(tight_layout=True)
hist = ax.hist2d(x, y)
3.2 自定义直方图
自定义2D直方图类似于1D情况,您可以控制可视组件,如存储箱大小或颜色规格化。
fig, axs = plt.subplots(3, 1, figsize=(5, 15), sharex=True, sharey=True, tight_layout=True)
# We can increase the number of bins on each axis
axs[0].hist2d(x, y, bins=40)
# As well as define normalization of the colors
axs[1].hist2d(x, y, bins=40, norm=colors.LogNorm())
# We can also define custom numbers of bins for each axis
axs[2].hist2d(x, y, bins=(80, 10), norm=colors.LogNorm())
plt.show()
3.3 贝叶斯方法样式表
from numpy.random import beta
import matplotlib.pyplot as plt
plt.style.use('bmh')
def plot_beta_hist(ax, a, b):
ax.hist(beta(a, b, size=10000), histtype="stepfilled", bins=25, alpha=0.8, density=True)
fig, ax = plt.subplots()
plot_beta_hist(ax, 10, 10)
plot_beta_hist(ax, 4, 12)
plot_beta_hist(ax, 50, 12)
plot_beta_hist(ax, 6, 55)
ax.set_title("'bmh' style sheet")
plt.show()
3.4 标准化直方图
用于标准化箱高度,使直方图的积分为1.得到的直方图是概率密度函数的近似值
import numpy as np
import matplotlib.pyplot as plt
# example data
mu = 100 # mean of distribution
sigma = 15 # standard deviation of distribution
x = mu + sigma * np.random.randn(437)
num_bins = 50
fig, ax = plt.subplots()
# the histogram of the data
n, bins, patches = ax.hist(x, num_bins, density=1)
# add a 'best fit' line
y = ((1 / (np.sqrt(2 * np.pi) * sigma)) *
np.exp(-0.5 * (1 / sigma * (bins - mu))**2))
ax.plot(bins, y, '--')
ax.set_xlabel('Smarts')
ax.set_ylabel('Probability density')
ax.set_title(r'Histogram of IQ: $\mu=100$, $\sigma=15$')
# Tweak spacing to prevent clipping of ylabel
fig.tight_layout()
plt.show()
- n:array or list of arrays
直方图箱的值。有关可能的语义的描述,请参见密度和权重。如果输入x是一个数组,那么这是一个长度为nbins的数组。
如果输入是数组序列[data 1,data 2,.],那么这是一个数组列表,其中包含每个数组的直方图值,顺序相同。
即使不使用加权或规范化,数组n(或其元素数组)的 dtype 始终是浮动的。 - bins:array
The edges of the bins. 长度nbins+1(nbins左边缘和右边缘的最后一桶)。即使传入多个数据集,也始终是单个数组。 - patches:BarContainer or list of a single Polygon or list of such objects
Container of individual artists used to create the histogram or list of such containers if there are multiple input datasets.
3.5 更改直方图颜色
直方图方法(除其他外)返回一个修补程序对象。这使我们可以访问所绘制对象的特性。使用这个,我们可以根据自己的喜好编辑直方图。让我们根据每个条的y值更改其颜色。
fig, axs = plt.subplots(1, 2, tight_layout=True)
# N is the count in each bin, bins is the lower-limit of the bin
N, bins, patches = axs[0].hist(x, bins=n_bins)
# We'll color code by height, but you could use any scalar
fracs = N / N.max()
# we need to normalize the data to 0..1 for the full range of the colormap
norm = colors.Normalize(fracs.min(), fracs.max())
# Now, we'll loop through our objects and set the color of each accordingly
for thisfrac, thispatch in zip(fracs, patches):
color = plt.cm.viridis(norm(thisfrac))
thispatch.set_facecolor(color)
# We can also normalize our inputs by the total number of counts
axs[1].hist(x, bins=n_bins, density=True)
# Now we format the y-axis to display percentage
axs[1].yaxis.set_major_formatter(PercentFormatter(xmax=1))
4、柱状图 plt.bar()
cate = ['Apple', 'Huawei', 'Xiaomi', 'Oppo', 'Vivo', 'Meizu']
data1 = [123, 153, 157, 107, 98, 142]
data2 = [56, 77, 93, 68, 45, 67]
plt.figure(figsize=(8, 5)) # 新建一个空画布,设置尺寸
plt.bar(cate, data1, label='总计')
plt.bar(cate, data2, label='线上')
plt.legend()
plt.title('各手机品牌销售额对比',
# 设置标题位置
loc="left")
plt.show()
4.1 图像不重叠
cate = ['Apple', 'Huawei', 'Xiaomi', 'Oppo', 'Vivo', 'Meizu']
data1 = [89, 45, 56, 74, 23, 21]
data2 = [56, 77, 93, 68, 45, 67]
x_location = np.arange(len(cate))
plt.figure(figsize=(8, 5))
plt.bar(x_location, data1, label='线下', width=0.3)
plt.bar(x_location+0.3, data2, label='线上', width=0.3)
# 为X轴设置刻度值
plt.xticks(x_location+0.15, cate)
plt.legend()
plt.title('各手机品牌销售额对比', loc="left",
# 设置标题字体
fontdict={'fontsize':18,'color':'red'})
plt.show()
4.2 横向柱状图 plt.barh()
如遇标签过长,可选择纵向显示图像
cate = ['Apple', 'Huawei', 'Xiaomi', 'Oppo', 'Vivo', 'Meizu']
data1 = [89, 45, 56, 74, 23, 21]
data2 = [56, 77, 93, 68, 45, 67]
x_location = np.arange(len(cate))
plt.figure(figsize=(8, 5)) # 新建一个空画布,设置尺寸
plt.barh(x_location, data1, label='线下', height=0.3)
plt.barh(x_location+0.3, data2, label='线上', height=0.3)
# 为X轴设置刻度值
plt.yticks(x_location+0.15, cate)
plt.legend()
plt.title('各手机品牌销售额对比', loc="left",
# 设置标题字体
fontdict={'fontsize':18,'color':'red'})
plt.show()
5、饼状图 plt.pie()
常用来表示同一等级中不同类别的占比情况。
cate = ['Apple', 'Huawei', 'Xiaomi', 'Oppo', 'Vivo', 'Meizu']
data = [153, 124, 107, 99, 89, 46]
plt.figure(figsize=(5, 5)) # 新建一个空画布,设置尺寸
plt.pie(data, labels=cate,
# 显示百分比,支持调用方法
autopct='%.2f%%')
plt.show()
5.1 立体饼状图
cate = ['Apple', 'Huawei', 'Xiaomi', 'Oppo', 'Vivo', 'Meizu']
data = [153, 124, 107, 99, 89, 46]
plt.figure(figsize=(5, 5)) # 新建一个空画布,设置尺寸
plt.pie(data, labels=cate,
# 对应类目偏移,0为不偏移
explode=[0,0.1,0,0,0.2,0],
autopct='%.2f%%',
shadow=True)
plt.show()
5.2 环形图
常用来表示同一层级不同类别之间的占比关系。
#环形图,建立坐标系
plt.subplot(1,1,1)
#指明x值
x1=np.array([8566,5335,7310,6482])
x2=np.array([4283,2667,3655,3241])
#绘图
labels=["东区","北区","南区","西区"]
plt.pie(x1,labels=labels,radius=1.0,wedgeprops={"width":0.3,"edgecolor":"w"})
plt.pie(x2,radius=0.7,wedgeprops={"width":0.3,"edgecolor":"w"})
#添加注释
plt.annotate("完成量",xy=(0.35,0.35),xytext=(0.7,0.45),
arrowprops={"facecolor":"black","arrowstyle":"->"})
plt.annotate("任务量",xy=(0.75,0.2),xytext=(1.1,0.2),
arrowprops={"facecolor":"black","arrowstyle":"->"})
#设置标题
plt.title("全国各区域任务量与完成量占比",loc="center")
5.3 极轴上的饼图
import numpy as np
import matplotlib.pyplot as plt
# Compute pie slices
N = 20
theta = np.linspace(0.0, 2 * np.pi, N, endpoint=False)
radii = 10 * np.random.rand(N)
width = np.pi / 4 * np.random.rand(N)
ax = plt.subplot(111, projection='polar')
bars = ax.bar(theta, radii, width=width, bottom=0.0)
# Use custom colors and opacity
for r, bar in zip(radii, bars):
bar.set_facecolor(plt.cm.viridis(r / 10.))
bar.set_alpha(0.5)
plt.show()
5.4 标签文本设置
cate = ['Apple', 'Huawei', 'Xiaomi', 'Oppo', 'Vivo', 'Meizu']
data = [153, 124, 107, 99, 89, 46]
plt.figure(figsize=(8, 8)) # 新建一个空画布,设置尺寸
plt.pie(data,
labels=cate,
explode=[0,0.1,0,0,0,0],
autopct='%.2f%%',
shadow=True,
# 自定义颜色,不需要于类目数相等,循环调用
colors=['#FFC0CB', '#FF00FF', '#FFD700', '#FFA500', '#00FF7F', 'blue'],
# 文本设置,包括字体,大小,颜色等属性
textprops={'fontsize':12,'color':'red'})
plt.legend()
plt.show()
6、散点图/气泡图 plt.scatter()
data_x = [random.randint(1, 100) for _ in range(1000)]
data_y = [random.randint(1, 100) for _ in range(1000)]
area = np.pi * (15 * np.random.rand(N))**2
plt.figure(figsize=(8, 8))
plt.scatter(data_x, data_y)
plt.show()
6.1 极轴上的散点图
import numpy as np
import matplotlib.pyplot as plt
# Compute areas and colors
N = 150
r = 2 * np.random.rand(N)
theta = 2 * np.pi * np.random.rand(N)
area = 200 * r**2
colors = theta
fig = plt.figure()
ax = fig.add_subplot(111, projection='polar')
c = ax.scatter(theta, r, c=colors, s=area, cmap='hsv', alpha=0.75)
6.2 极轴偏移原点的散点图
与先前图的主要区别在于原点半径的配置,产生环。 此外,θ零位置设置为旋转图。
fig = plt.figure()
ax = fig.add_subplot(111, polar=True)
c = ax.scatter(theta, r, c=colors, s=area, cmap='hsv', alpha=0.75)
ax.set_rorigin(-2.5)
ax.set_theta_zero_location('W', offset=10)
6.3 极轴上的扇区散点图
与之前的图表的主要区别在于theta开始和结束限制的配置,产生扇区而不是整圆。
fig = plt.figure()
ax = fig.add_subplot(111, polar=True)
c = ax.scatter(theta, r, c=colors, s=area, cmap='hsv', alpha=0.75)
ax.set_thetamin(45)
ax.set_thetamax(135)
plt.show()
6.4 颜色/大小/透明度 设置
plt.scatter(x, y,
s=area, # 图形大小
c=colors, # 颜色
alpha=0.3) # 透明度
7、面积图 plt.stackplot()
plt.subplot(111)
x = np.array([1,2,3,4,5,6,7,8,9])
y1 = np.array([866,2335,5710,6482,6120,1605,3813,4428,4631])
y2 = np.array([433,1167,2855,3241,3060,802,1906,2214,2315])
labels = ["注册人数","激活人数"]
plt.stackplot(x,y1,y2,labels=labels)
plt.title("XXX公司1-9月注册与激活人数",color='k')
plt.xlabel('月份')
plt.ylabel('注册与激活人数')
plt.xticks(x,["1月","2月","3月","4月","5月","6月","7月","8月","9月"])
plt.grid(False)
plt.legend()
8、箱型图 plt.boxplot()
用来反映一组数据离散程度。
plt.subplot(1,1,1)
y1 = np.array([866,2335,5710,6482,6120,1605,3813,4428,4631])
y2 = np.array([433,1167,2855,3241,3060,802,1906,2214,2315])
x = [y1,y2]
#绘图
labels = ["注册人数","激活人数"]
plt.boxplot(x,labels=labels,vert=True,widths=[0.2,0.5])
plt.title("XXX公司1-9月注册与激活人数",loc="center")
plt.grid(False)
9、热力图 plt.imshow()
import itertools
cm = np.array([[1,0.082,0.031,-0.0086],[0.082,1,-0.063,0.062],
[0.031,-0.09,1,0.026],[-0.0086,0.062,0.026,1]])
cmap = plt.cm.cool #设置配色方案
plt.imshow(cm,cmap=cmap)
plt.colorbar() #显示右边的颜色条
#设置x轴和y轴的刻度标签
classes=["负债率","信贷数量","年龄","家属数量"]
tick_marks = np.arange(len(classes))
plt.xticks(tick_marks,classes)
plt.yticks(tick_marks,classes)
#将数值显示在指定位置
for i,j in itertools.product(range(cm.shape[0]),range(cm.shape[1])):
plt.text(j,i,cm[i,j],ha="center")
plt.grid(False) #设置网格线
plt.show()
10、多图融合
10.1 折线图+柱形图
plt.subplot(111)
#指明x和y的值
x=np.array([1,2,3,4,5,6,7,8,9])
y1=np.array([866,2335,5710,6482,6120,1605,3813,4428,4631])
y2=np.array([433,1167,2855,3241,3060,802,1906,2214,2315])
#直接绘制折线图和柱形图
plt.plot(x,y1,linestyle='-',color='k',linewidth=1,marker='o',markersize=3,label='注册人数')
plt.bar(x,y2,color='k',label='激活人数')
#设置标题
plt.title('XXX公司1-9月注册与激活人数',loc='center')
#数据标签
for a,b in zip(x,y1):
plt.text(a,b,b,ha='center',va='bottom',fontsize=11)
for a,b in zip(x,y2):
plt.text(a,b,b,ha='center',va='bottom',fontsize=11)
plt.xlabel('月份')
plt.ylabel('注册量')
#设置x轴和y轴的刻度
plt.xticks(np.arange(1,10,1),["1月份","2月份","3月份","4月份","5月份","6月份","7月份","8月份","9月份"])
plt.yticks(np.arange(1000,7000,1000),["1000人","2000人","3000人","4000人","5000人","6000人"])
plt.legend()
10.2 折线图+折线图
将两条及以上的折线画在统一坐标系中,建立坐标系后,直接依次运行多行绘制折线图代码即可。
plt.figure(figsize=(10,6))
#指明x和y的值
x = np.array([1,2,3,4,5,6,7,8,9])
y1 = np.array([866,2335,5710,6482,6120,1605,3813,4428,4631])
y2 = np.array([433,1167,2855,3241,3060,802,1906,2214,2315])
#直接绘制两条折线
plt.plot(x,y1,color='k',linestyle='-',linewidth=1,marker='o',markersize=4,label='注册人数')
plt.plot(x,y2,color='r',linestyle='--',linewidth=1,marker='o',markersize=4,label='激活人数')
#设置标题
plt.title('XXX公司1-9月注册与激活人数',loc='center')
#添加数据标签
for a,b in zip(x,y1):
plt.text(a,b,b,ha='center',va='bottom',fontsize=11)
for a,b in zip(x,y2):
plt.text(a,b,b,ha='center',va='bottom',fontsize=11)
#设置x轴和y轴的名称
plt.xlabel('月份')
plt.ylabel('注册量')
#设置x轴和y轴的刻度
plt.xticks(np.arange(1,10,1),["1月份","2月份","3月份","4月份","5月份","6月份","7月份","8月份","9月份"])
plt.yticks(np.arange(1000,7000,1000),["1000人","2000人","3000人","4000人","5000人","6000人"])
#设置图例
plt.legend()
11、双坐标轴图表
既有主坐标轴又有次坐标轴,当两个不同量级的指标放在同一坐标系中,就需要开启双坐标轴。
11.1 双y轴图表
一个坐标系中有两条y轴,使用plt库中的twinx方法,流程为:先建立坐标系,然后绘制主坐标轴上的图表,再调用plt.twinx方法,最后绘制次坐标轴上的图表。
plt.subplot(111)
x = np.array([1,2,3,4,5,6,7,8,9])
y1 = np.array([866,2335,5710,6482,6120,1605,3813,4428,4631])
y2 = np.array([0.544,0.324,0.390,0.411,0.321,0.332,0.922,0.029,0.157])
plt.plot(x,y1,color='k',linestyle='-',linewidth=1,marker='o',markersize=3,label='注册人数')
plt.xlabel('月份')
plt.ylabel('注册量')
plt.legend(loc='upper left')
plt.twinx() #调用twinx方法
plt.plot(x,y2,color='r',linestyle='-.',linewidth=1,marker='o',markersize=3,label='激活率')
plt.xlabel('月份')
plt.ylabel('激活率')
plt.legend()
plt.title('XXX公司1-9月注册量与激活率')
11.2 双x轴图表
一个坐标系中有两条x轴,使用plt库中的twiny方法,具体流程跟双y轴完全一样。
参考:
- Matplotlib可视化教程:https://www.heywhale.com/mw/project/5e6e2053dd480d002c22953c
- python–数据可视化 :https://www.heywhale.com/mw/project/5d227bf2688d36002c54a54c
- 50题matplotlib从入门到精通:https://www.heywhale.com/mw/project/5de9f0a0953ca8002c95d2a9
- 美人图:5分钟上手Matplotlib:https://www.heywhale.com/mw/project/5ed31e64fab96c002cf64acb
- Python数据可视化方法之matplotlib:https://www.heywhale.com/mw/project/5ddd1cccca27f8002c4a412c
- matplotlib数据可视化:https://www.heywhale.com/mw/project/5c35a9f6e691ba002c3a40df