一、认识多子图
一次画出多个表图
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
plt.rcParams['font.sans-serif'] = 'KaiTi'
plt.rcParams['axes.unicode_minus'] = False
# 二维数组的2行*2列(从0开始)四个位置[0,0],[0,1],[1,0],[1,1]
x = np.arange(5)
y = np.array([30,87,45,66,90])
# 二维数组
fig,ax = plt.subplots(3,2)
ax[0,1].plot(x,y)
ax[1,0].bar(x,y,width=0.3)
ax[2,1].barh(x,y,height=0.3)
# 一维,ax1是第一行。ax2是第二行。......
# ax1[0] == 第一行第一个, ax1[1] == 第一行第二个
# fig,(ax1,ax2,ax3) = plt.subplots(3,2)
# ax1[0].plot(x,y)
# ax2[1].bar(x,y,width=0.3)
# ax3[1].bar(x,y,width=0.1)
plt.show()
二、猫狗占比条形图
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
plt.rcParams['font.sans-serif'] = 'KaiTi'
plt.rcParams['axes.unicode_minus'] = False
y = np.arange(12)
x1 = np.array([19,33,28,29,14,24,87,6,26,15,27,39])
x2 = np.array([25,33,58,39,15,64,29,23,22,11,27,50])
labels = np.array(['中国','加拿大','巴西','澳大利亚',
'日本','墨西哥','俄罗斯','韩国',
'瑞士','土耳其','英国','美国'])
fig,(ax1,ax2) = plt.subplots(1,2)
# 背景颜色
ax1.set_facecolor('w')
ax1.barh(y,x1,height=0.3,
# color=''
)
ax1.set_title('部分国家养猫人群比例')
ax1.set_yticks(y,labels)
ax1.set_xlabel('人群比例(%)')
# 边框的大小
ax1.set_xlim(0,x1.max()+10)
for a,b in zip(x1,y):
ax1.text(a+4,b,'%d'%a,ha='center', va = 'center')
ax2.set_facecolor('w')
ax2.barh(y,x2,height=0.3,
# color=''
)
ax2.set_title('部分国家养狗人群比例')
ax2.set_yticks(y,labels)
ax2.set_xlabel('人群比例(%)')
# 边框的大小
ax2.set_xlim(0,x2.max()+10)
for a,b in zip(x2,y):
ax2.text(a+4,b,'%d'%a,ha='center', va = 'center')
plt.tight_layout()
plt.show()
这时你会发现:
fig,ax = plt.subplots(3,2) - 画出3行2列的表格
fig,(ax1,ax2) = plt.subplots(1,2) - 画出1行2列的表格
那我不想要生成表格,只想要在某个区域生成需要的表格,那我们就 进入了标题三
三、自定义区域
plt.subplot2grid()
是 Matplotlib 库中用于创建灵活的子图网格布局的函数。与 plt.subplot()
相比,它允许子图跨越多个网格单元,从而实现更复杂的布局。
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
plt.figure(num='多子图', figsize=(12, 8), facecolor='w')
plt.rcParams['font.sans-serif'] = 'KaiTi'
plt.rcParams['axes.unicode_minus'] = False
x = np.arange(5)
y = [1,5,4,7,2]
# shape:规模
# loc:位置
# rowspan:向下跨越的行数(默认1)
# colspan:向右跨越的列数(默认1)
ax1 = plt.subplot2grid((2,3),(0,0),rowspan=1,colspan=2)
ax1.plot(x,y,'g--*')
ax1.set_facecolor('w')
# ax2 = plt.subplot2grid((2,3),(0,0))
# ax2.bar(x,y,width=0.2)
ax3 = plt.subplot2grid((2,3),(0,2),rowspan=3,colspan=1)
ax3.barh(x,y,height=0.3)
ax3.set_facecolor('w')
plt.show()
四、用户数据分析
4.1 柱形和饼图
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
plt.figure(num='图', figsize=(12, 8), facecolor='w')
plt.rcParams['font.sans-serif'] = 'KaiTi'
plt.rcParams['axes.unicode_minus'] = False
data_2017 = np.array([21, 35, 22, 19, 1])
data_2018 = np.array([13, 32, 27, 27, 1])
x = np.arange(5)
y = np.array([51, 73, 99, 132, 45])
labels = np.array(['一线', '二线', '三线', '四线及以外', '其他国家地区'])
# 计算线的平均值
ave = np.average(y)
bar_width = 0.4
ax1.axhline(y=ave,ls=':',lw=1, color='m')
for a, b in zip(x, y):
ax1.text(a, b + 2.5, '%d' % b, ha='center', va='center')
ax1.legend(['平均增长倍数','地区',])
ax2 = plt.subplot2grid((3, 2), (2, 0), rowspan=1, colspan=1)
ax2.pie(data_2017,radius=1.2,autopct='%3.1f%%',labels=labels,
colors=['#2f4f4f','#ff0000','#A9A9A9','#ffd700','#b0c4de'])
ax2.set_title('2017年抖音用户地区分布的比例',y=1.1)
ax3 = plt.subplot2grid((3, 2), (2, 1), rowspan=1, colspan=1)
ax3.pie(data_2018,radius=1.2,autopct='%3.1f%%',labels=labels,
colors=['#2f4f4f','#ff0000','#A9A9A9','#ffd700','#b0c4de'])
ax3.set_title('2018年抖音用户地区分布的比例',y=1.1)
plt.tight_layout()
plt.show()
4.2 饼图和条形
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
plt.figure(num='图', figsize=(12, 8), facecolor='w')
plt.rcParams['font.sans-serif'] = 'KaiTi'
plt.rcParams['axes.unicode_minus'] = False
data_2017 = np.array([21, 35, 22, 19, 1])
data_2018 = np.array([13, 32, 27, 27, 1])
x = np.arange(5)
y = np.array([51, 73, 99, 132, 45])
labels = np.array(['一线', '二线', '三线', '四线及以外', '其他国家地区'])
ave = np.average(y)
bar_width = 0.4
ax1 = plt.subplot2grid((2, 3), (0, 1), rowspan=2, colspan=2)
ax1.barh(x, y, height=bar_width, color='#20B2aa')
ax1.set_yticks(x, labels, fontsize=13)
ax1.set_title('抖音2018 VS 2017人群增长倍数', fontsize=20, color='r')
ax1.set_xlabel('增长倍数', fontsize=13)
ax1.set_xlim(0, 140)
for a, b in zip(np.arange(5), y):
ax1.text(b + 2, a, '%d' % b, ha='left', va='center')
ax1.legend(['平均增长倍数'])
ax2 = plt.subplot2grid((2, 3), (0, 0), rowspan=1, colspan=1)
ax2.pie(data_2017,radius=1.2,autopct='%3.1f%%',labels=labels,
colors=['#2f4f4f','#ff0000','#A9A9A9','#ffd700','#b0c4de'],
explode=[0.1, 0.1, 0.1, 0.1, 0.1], shadow=True,)
ax2.set_title('2017年抖音用户地区分布的比例',y=1.1)
ax3 = plt.subplot2grid((2, 3), (1, 0), rowspan=1, colspan=1)
ax3.pie(data_2018,radius=1.2,autopct='%3.1f%%',labels=labels,
colors=['#2f4f4f','#ff0000','#A9A9A9','#ffd700','#b0c4de'],
explode=[0.1, 0.1, 0.1, 0.1, 0.1], shadow=True,)
ax3.set_title('2018年抖音用户地区分布的比例',y=1.1)
plt.tight_layout()
plt.show()
五、共享图
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
plt.rcParams['font.sans-serif'] = 'KaiTi'
plt.rcParams['axes.unicode_minus'] = False
x = np.arange(1, 13)
y1 = np.array([2.0, 2.2, 3.3, 4.5, 6.3, 10.2, 20.3, 33.4, 23.0, 16.5, 12.0, 6.2])
y2 = np.array([2.6, 5.9, 9.0, 26.4, 28.7, 70.7, 175.6, 182.2, 48.7, 18.1, 6.0, 2.3])
y3 = np.array([2.0, 4.9, 7.0, 23.2, 25.6, 76.7, 135.6, 162.2, 32.6, 20.0, 6.4, 3.3])
labels = []
for i in x:
labels.append(str(i) + '月')
fig, ax = plt.subplots(1, 1)
# 蒸发量
bar1 = ax.bar(x, y3, width=0.6)
# 降水量
bar2 = ax.bar(x, y2, bottom=y3, width=0.6)
ax.set_xticks(x, labels)
ax.set_title('平均气温与降水量、蒸发量的共享')
ax.set_ylabel('水量(ml)')
# 要共享数据1的图才可以画折线图
# 共享两个图
ax1 = ax.twinx()
# 折线图
plot1 = ax1.plot(x,y1,'m-o')
for a, b in zip(x, y1): # zip()转换成列表型
plt.text(a, b+1.3, '%d℃' % b, ha='right', va='top') # va='center'
ax1.set_ylabel('气温(℃)')
# plot1[0] 表示第一条线,因为折线图中可存在多个线,所有我们取第一条
plt.legend([bar1,bar2,plot1[0]],['蒸发量', '降水量','平均气温'], shadow=True, fancybox=True)
plt.savefig('平均气温与降水量、蒸发量的共享.png',dpi=720)
plt.show()
六、布局方式
6.1 约束布局
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
plt.rcParams['font.sans-serif'] = 'KaiTi'
plt.rcParams['axes.unicode_minus'] = False
# 约束布局,效果跟下面的一样
# plt.rcParams['figure.constrained_layout.use'] = True
# contrained_layout=True: 约束布局
# 特点:把每一个图定义差不多相同的大小;其主要设计目的是自动对图表的各个元素进行调整,以此避免元素之间出现重叠的情况
fig,(ax1,ax2) = plt.subplots(2,2,
constrained_layout=True
)
ax1[0].set_title('图1')
ax1[1].set_title('图2')
ax2[0].set_title('图3')
ax2[1].set_title('图4')
plt.show()
6.2 紧密布局
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
plt.rcParams['font.sans-serif'] = 'KaiTi'
plt.rcParams['axes.unicode_minus'] = False
fig,(ax1,ax2) = plt.subplots(2,2,)
ax1[0].set_title('图1')
ax1[1].set_title('图2')
ax2[0].set_title('图3')
ax2[1].set_title('图4')
# 紧密布局
# pad: 边缘的空白距离 1.08(默认)
# h_pad:上下相邻的距离
# w_pad:左右相邻的距离
plt.tight_layout(pad=2,h_pad=2,w_pad=0.5)
plt.show()
七、自定义布局
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
fig = plt.figure(num='自定义布局', figsize=(12, 8), facecolor='w')
plt.rcParams['font.sans-serif'] = 'KaiTi'
plt.rcParams['axes.unicode_minus'] = False
# 自定义画布,并不是自定义图
spec1 = fig.add_gridspec(3,3)
ax1 = fig.add_subplot(spec1[0,0:])
ax1.plot([1,3,2,5])
ax1 = fig.add_subplot(spec1[1,0:2])
ax1.plot([1,3,5,8])
ax1 = fig.add_subplot(spec1[2,0])
ax1.plot([1,3,52,10])
ax1 = fig.add_subplot(spec1[2,1])
ax1.plot([12,23,2,1])
ax1 = fig.add_subplot(spec1[1:,2:])
ax1.plot([12,23,2,1])
plt.tight_layout()
plt.show()