总结:本文为和鲸python 可视化探索训练营资料整理而来,加入了自己的理解(by GPT4o)
原作者:作者:大话数据分析,知乎、公众号【大话数据分析】主理人,5年数据分析经验,前蚂蚁金服数据运营,现京东经营分析师。
原活动链接
目录
- 第二节 Matplotlib高级图表与组合图表
- 一、Matplotlib高级图表
- 1.箱线图
- 2.圆环图
- ⏳跟练题目1
- 3.面积图
- 并列柱状图
- 双Y轴图
- 4.气泡图
- ⏳跟练题目2
- 5.雷达图
- 二、Matplotlib组合图表
- 1.组合图表
- 1.1折线图+折线图
- 1.2柱形图+折线图
- 2.建立坐标系
- 2.1plt.subplot2gird建系
- 2.2plt.subplot建系
- ⏳跟练题目3
- 2.3plt.subplots建系
- 2.4add_subplot建系
- 三、闯关题
- STEP1: 按照要求计算下方题目结果
第二节 Matplotlib高级图表与组合图表
本节将深入探索Matplotlib高级图表和组合图表制作。你将掌握箱线图、圆环图、面积图等的创建技巧,直观揭示数据规律和关系。同时,学习制作组合图表,精准建立坐标系,调整图表位置和大小。通过本节的学习,你不仅能够掌握各种高级图表和组合图表的创建方法,还能深化对数据的理解,提升数据可视化方面的技能,为经管领域的学术研究或实践工作提供有力的支持。
总结:在学习面积图时需要注意,活动原本的代码有误,如果两个维度的数据相对大小关系不确定,使用面积图绘制会产生错误。
核心知识点
1.Matplotlib高级图表:
- 箱线图
- 圆环图
- 面积图
- 气泡图
- 雷达图
2.Matplotlib组合图表:
- 组合图表
- 建立坐标系
一、Matplotlib高级图表
1.箱线图
箱线图是一种用作显示一组数据分散情况资料的统计图。这种图包含了一些统计学的关键数据点,如最大值、最小值、中位数以及上下四分位数。通过箱线图,可以直观地看出数据的分散程度和分布情况。
**plt.boxplot():**用于绘制箱线图
函数签名
plt.boxplot(x, notch=False, sym=‘o’, vert=True, whis=1.5, positions=None, widths=0.5, patch_artist=False, meanline=False, showmeans=False, showcaps=True, showbox=True, showfliers=True, boxprops=None, labels=None, flierprops=None, medianprops=None, meanprops=None, capprops=None, whiskerprops=None, manage_ticks=True, autorange=False, zorder=None, *, data=None)
参数解释
- x:指定要绘制箱线图的数据,可以是一个数组或多个数组的序列。
- notch:布尔值,用于设置箱线图是否以缺口形式显示中位数置信区间。默认为False。
- sym:指定异常值的符号。默认为’o’。
- vert:布尔值,用于设置箱线图的方向,True表示垂直方向,False表示水平方向。默认为True。
- whis:浮点数,用于设置须线(whiskers)的长度。默认为1.5。
- positions:数组类型,用于设置每个箱线图的位置。默认为None。
- widths:浮点数,用于设置每个箱线图的宽度。默认为0.5。
- patch_artist:布尔值,用于设置箱线图的颜色填充。默认为False。
- meanline:布尔值,用于设置是否显示均值线。默认为False。
- showmeans:布尔值,用于设置是否显示均值点。默认为False。
- showcaps:布尔值,用于设置是否显示箱线图顶部的须线。默认为True。
- showbox:布尔值,用于设置是否显示箱线图箱体。默认为True。
- showfliers:布尔值,用于设置是否显示异常值。默认为True。
- boxprops:字典类型,用于设置箱体的属性,例如颜色、边框等。默认为None。
- labels:列表字符串,用于设置每个箱线图的标签。默认为None。
- flierprops:字典类型,用于设置异常值的属性,例如标记样式、颜色等。默认为None。
- medianprops:字典类型,用于设置中位数的属性,例如线条样式、颜色等。默认为None。
- meanprops:字典类型,用于设置均值的属性,例如标记样式、颜色等。默认为None。
- capprops:字典类型,用于设置箱线图顶部的属性,例如线条样式、颜色等。默认为None。
- whiskerprops:字典类型,用于设置须线的属性,例如线条样式、颜色等。默认为None。
- manage_ticks:布尔值,是否自动管理刻度的位置和标签。默认为True。
- autorange:布尔值,是否自动调整图像的范围以适应数据。默认为False。
- zorder:设置图形的堆叠顺序。默认为None。
- data:接受一个可以转换为数据对象的数据,此参数与x参数互斥。
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt # 导入matplotlib包
import matplotlib.style as psl
import warnings
# 魔法命令,用于在笔记本内联显示matplotlib图表
%matplotlib inline
# 确保图表以SVG格式显示
%config InlineBackend.figure_format = 'svg'
warnings.filterwarnings("ignore") # 忽略警告信息
plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号
plt.rcParams['figure.dpi'] = 100 # 分辨率
psl.use('ggplot')
plt.figure(figsize=(9, 6)) # 设置图表画布大小
plt.title('电商销售利润箱线图')
# 指定绘制箱线图的数据
x = pd.DataFrame(data={'利润': np.random.randn(1000)})
plt.boxplot(x.values, # 指定绘制箱线图的数据
whis=1.5, # 指定1.5倍的四分位数差
widths=0.1, # 指定箱线图中箱子的宽度为0.3
showmeans=True, # 显示均值
labels=['利润'],
patch_artist=True, #填充箱子的颜色
boxprops={'facecolor':'RoyalBlue'}, #指定箱子的填充色为宝蓝色
flierprops={'markerfacecolor': 'red','markeredgecolor': 'red','markersize': 3},# 指定异常值的填充色、边框色和大小
meanprops={'marker': 'h','markerfacecolor': 'black','markersize': 8},# 指定中位数的标记符号(虚线)和颜色
medianprops={'linestyle': '--','color': 'orange'},# 指定均值点的标记符号(六边形)、填充色和大小
)
# 显示图像
plt.show()
箱线图说明:箱线图(Box Plot)是一种统计图表,用于显示数据分布的五个关键数字:最小值、第一四分位数(Q1)、中位数(Q2)、第三四分位数(Q3)和最大值。它提供了一种可视化方法来理解数据的集中趋势、分散程度和可能的异常值。以下是箱线图的详细解析:
-
中位数(Q2):
- 箱体内部的横线表示数据的中位数,即将数据分成上下两部分的点。
-
第一四分位数(Q1)和第三四分位数(Q3):
- 箱体的下边缘表示第一四分位数(Q1),即数据的下25%点。
- 箱体的上边缘表示第三四分位数(Q3),即数据的上75%点。
-
四分位间距(IQR):
- IQR = Q3 - Q1,表示中间50%数据的范围。箱体的高度即为IQR。
-
须(Whiskers):
- 须通常延伸至最大值和最小值,但在传统箱线图中,须只延伸到1.5倍IQR范围内的最小和最大值。
- 超出1.5倍IQR的点被认为是异常值(outliers),并以独立的点标示。
-
异常值(Outliers):
- 异常值是远离数据其他部分的点,通常用小圆点或星号表示。
2.圆环图
圆环图是一种数据可视化图表,它类似于饼图,但中间有一个空白区域,形成环状。圆环图通过扇区的大小和颜色来展示数据的比例关系。
**plt.pie():**也可以用来绘制圆环图,通过在 wedgeprops 参数中设置饼图部分的边缘颜色和填充颜色为透明,可以实现圆环图的效果。
函数签名
plt.pie(x, explode=None, labels=None, colors=None, autopct=None,pctdistance=0.6, labeldistance=1.1, startangle=None,radius=1, counterclock=True, wedgeprops=None, textprops=None,center=(0, 0), framesize=6, rotatelabels=False, *,normalize=False, data=None, **kwargs)
参数解释
- x:数组类型,用于指定每个扇形区域的大小。这些值将被归一化,所以它们的总和为1,每个值对应饼图的一个部分;
- explode:用于设置饼图每个部分离中心的距离。默认为None,表示所有部分都紧贴着中心。如果提供一个数组,则数组的长度应与x的长度相同,并且每个元素表示对应部分离中心的距离;
- labels:列表字符串,用于设置每个饼图部分的标签。默认为None;
- colors:用于设置饼图部分的颜色。可以是颜色名称、RGB元组或十六进制颜色字符串。如果为None,将使用Matplotlib的默认颜色循环;
- autopct:字符串或函数,用于控制饼图百分比的显示方式。如果为字符串,可以使用格式化的浮点数(例如’%.1f%%')。如果为函数,函数应接收一个百分比值,并返回一个字符串;
- pctdistance:浮点数,用于设置百分比标签与圆心的距离,默认为0.6;
- labeldistance:浮点数,用于设置标签与圆心的距离,默认为1.1;
- startangle:浮点数,用于设置饼图的起始角度,默认为从x轴正半轴开始逆时针计算角度;
- radius:浮点数或两个浮点数的元组,用于设置饼图的半径。如果为单个浮点数,则所有饼图部分都有相同的半径。如果为元组,则第一个元素为内半径(用于生成环形饼图),第二个元素为外半径;
- counterclock:布尔值,用于设置饼图是顺时针还是逆时针排列,默认为True(逆时针);
- wedgeprops:字典类型,用于设置饼图部分的属性,例如边缘颜色、线宽等;
- textprops:字典类型,用于设置文本标签的属性,例如字体大小、颜色等;
- center:两个浮点数的元组,用于设置饼图的中心点位置。默认为(0, 0);
- framesize:整数,用于设置饼图的框架大小;
- rotatelabels:布尔值,用于设置标签是否应旋转以与饼图部分对齐。默认为False;
- normalize:布尔值,是否将输入数据归一化到1。如果为True,则忽略数据中的任何缺失值。默认为False;
- data:可选参数,接受一个字典或可以转换为字典的对象。此参数与x参数互斥。
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt # 导入matplotlib包
import matplotlib.style as psl
# 魔法命令,用于在笔记本内联显示matplotlib图表
%matplotlib inline
# 确保图表以SVG格式显示
%config InlineBackend.figure_format = 'svg'
psl.use('ggplot')
plt.figure(figsize=(9, 6)) # 设置图表画布大小
#导入数据
df=pd.DataFrame(data={'区域':['华东','华北','东北','西北','西南','华南'],
'销售数': np.random.randint(low=100,high=1000,size=6),
'销售额': np.random.randint(low=1000,high=10000,size=6)}
)
x=df['区域'].tolist()
y1=df['销售数'].tolist()
y2=df['销售额'].tolist()
#绘制圆环图
plt.pie(y1,#用于绘制饼图的数据,表示每个扇形的面积
labels=x,#各个扇形的标签,默认值为 None。
radius=1
,#设置饼图的半径,默认为 1
wedgeprops= dict(edgecolor = "w",width = 0.2),#指定扇形的属性,比如边框线颜色、边框线宽度等
autopct='%.1f%%',#设置饼图内各个扇形百分比显示格式,%0.1f%% 一位小数百分比
pctdistance=0.9#指定 autopct 的位置刻度
)
plt.pie(y2,#用于绘制饼图的数据,表示每个扇形的面积
#labels=x,
radius=0.8,#设置饼图的半径,默认为 1
wedgeprops= dict(edgecolor = "w",width = 0.2),#指定扇形的属性,比如边框线颜色、边框线宽度等
autopct='%.1f%%',#设置饼图内各个扇形百分比显示格式,%0.1f%% 一位小数百分比
pctdistance=0.8#指定 autopct 的位置刻度
)
#设置标题
plt.title("各区域销售数和销售额占比", loc = "center")
#图像展示
plt.show()
⏳跟练题目1
✍跟练1:假如你是一名销售选品人员,需要研究各个商品的销售额占比情况,你可以用圆环图来直观地展示销售品类的构成和占比关系,通过圆环图分析,你可以快速识别出销售额较高的产品类别和占比,以及它们在整体销售品类中的相对重要性,从而做出正确的选品。
💡 提示:案例数据可使用下面定义的数据集,包含商品名称、商品价格、购买数量等字段,计算销售额数据代码df['销售额']=df['商品价格']*df['购买数量']
,做出来的圆环图应该与下面的图表类似。
import pandas as pd
# 定义数据
data = {'用户ID': [1001, 1002, 1003, 1001, 1002, 1003, 1004, 1005, 1006, 1007],
'商品名称': ['手机', '电视', '电脑', '耳机', '耳机', '键盘', '耳机', '键盘', '键盘', '手机'],
'商品价格': [1999, 4999, 5999, 99, 299, 199, 499, 399, 129, 1299],
'购买数量': [2, 1, 1, 3, 1, 2, 1, 1, 3, 1]}
# 创建 DataFrame
df = pd.DataFrame(data)
df
用户ID | 商品名称 | 商品价格 | 购买数量 | |
---|---|---|---|---|
0 | 1001 | 手机 | 1999 | 2 |
1 | 1002 | 电视 | 4999 | 1 |
2 | 1003 | 电脑 | 5999 | 1 |
3 | 1001 | 耳机 | 99 | 3 |
4 | 1002 | 耳机 | 299 | 1 |
5 | 1003 | 键盘 | 199 | 2 |
6 | 1004 | 耳机 | 499 | 1 |
7 | 1005 | 键盘 | 399 | 1 |
8 | 1006 | 键盘 | 129 | 3 |
9 | 1007 | 手机 | 1299 | 1 |
df['销售额']=df['商品价格']*df['购买数量']
df_temp = df.groupby(by = ['商品名称'])['销售额'].sum().reset_index()
df_temp
商品名称 | 销售额 | |
---|---|---|
0 | 手机 | 5297 |
1 | 电脑 | 5999 |
2 | 电视 | 4999 |
3 | 耳机 | 1095 |
4 | 键盘 | 1184 |
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt # 导入matplotlib包
import matplotlib.style as psl
# 魔法命令,用于在笔记本内联显示matplotlib图表
%matplotlib inline
# 确保图表以SVG格式显示
%config InlineBackend.figure_format = 'svg'
psl.use('ggplot')
plt.figure(figsize=(9, 6)) # 设置图表画布大小
#绘制圆环图
plt.pie(df_temp['销售额'].tolist(),#用于绘制饼图的数据,表示每个扇形的面积
labels=df_temp['商品名称'].tolist(),#各个扇形的标签,默认值为 None。
radius=1.0,#设置饼图的半径,默认为 1
wedgeprops= dict(edgecolor = "w",width = 0.2),#指定扇形的属性,比如边框线颜色、边框线宽度等
autopct='%.1f%%',#设置饼图内各个扇形百分比显示格式,%0.1f%% 一位小数百分比
pctdistance=0.9#指定 autopct 的位置刻度
)
#设置标题
plt.title("各品类销售额占比", loc = "center")
#图像展示
plt.show()
3.面积图
面积图是一种统计图表形式,用于显示数据随时间或其他连续变量的变化趋势。它通过填充折线与坐标轴之间的区域,形成一个封闭的面积,以强调数据的累积趋势和相对大小。
**plt.stackplot():**可用于绘制堆叠面积图。
函数签名
plt.stackplot(x, *args, labels=(), colors=None, baseline=‘zero’, **kwargs)
参数解释
- x:数组类型,表示横坐标的值。
- *args:不定长参数,表示要堆叠的数据。每个参数对应一个数据序列,数据序列的数量决定了堆叠的层数。
- labels:字符串序列,表示每个数据序列的标签。默认为空元组 ()。
- colors:颜色或颜色序列,用于设置每个数据序列的颜色。可以是颜色名称、RGB 元组、十六进制颜色字符串等。默认为 None,使用默认的颜色循环。
- baseline:字符串,用于设置基线的类型。可选值有 ‘zero’(基线为 0)、‘sym’(基线为 y=0 的对称线)、‘wiggle’(基线为数据的均值)、‘weighted_wiggle’(基线为数据的加权均值)。默认为 ‘zero’。
- **kwargs:其他可选参数,例如线型、线宽等,可以通过关键字参数传递。这些参数将被应用于所有数据序列。
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt # 导入matplotlib包
import matplotlib.style as psl
# 魔法命令,用于在笔记本内联显示matplotlib图表
%matplotlib inline
# 确保图表以SVG格式显示
%config InlineBackend.figure_format = 'svg'
psl.use('ggplot')
plt.figure(figsize=(9, 6)) # 设置图表画布大小
np.random.seed(42)
#导入数据(注意此处数据相对大小确定,如果数据相对大小不确定出来的图是错的)
df=pd.DataFrame(data={'日期': pd.date_range('20231101',periods=30),
'进货价格': np.random.randint(low=100,high=200,size=30),
'实际售价': np.random.randint(low=200,high=500,size=30)}
)
print(df)
x=df['日期'].astype('str').tolist()
y1=df['进货价格'].tolist()
y2=df['实际售价'].tolist()
#绘制面积图
plt.stackplot(x, y1, y2, labels = ["进货价格","实际售价"] )
#设置标题
plt.title("双十一进货价格与实际售价对比面积图",loc ="center")
#设置x和y轴的名称
plt.xlabel("日期")
plt.ylabel("价格")
#设置X坐标轴刻度
plt.xticks(x, ['{}日'.format(i+1) for i in range(30)],rotation=45)
#设置图例
plt.legend(loc = "upper right",frameon=False)
#图像展示
plt.show()
日期 进货价格 实际售价
0 2023-11-01 151 258
1 2023-11-02 192 369
2 2023-11-03 114 387
3 2023-11-04 171 470
4 2023-11-05 160 389
5 2023-11-06 120 374
6 2023-11-07 182 250
7 2023-11-08 186 254
8 2023-11-09 174 443
9 2023-11-10 174 330
10 2023-11-11 187 334
11 2023-11-12 199 220
12 2023-11-13 123 366
13 2023-11-14 102 473
14 2023-11-15 121 288
15 2023-11-16 152 213
16 2023-11-17 101 441
17 2023-11-18 187 464
18 2023-11-19 129 252
19 2023-11-20 137 291
20 2023-11-21 101 463
21 2023-11-22 163 234
22 2023-11-23 159 405
23 2023-11-24 120 280
24 2023-11-25 132 249
25 2023-11-26 175 201
26 2023-11-27 157 253
27 2023-11-28 121 305
28 2023-11-29 188 459
29 2023-11-30 148 390
注意
面积图有时可能会导致视觉上的误导,特别是在数据的相对大小和相对变化上。原因在于面积图的层次会叠加在一起,较小的数值会被较大的数值“压住”,因此看起来总是比另外一个小。这种图适合相对大小明确的数据比如季度累计数据对比,二季度的累计数值肯定会比一季度值要大
为了更好地反映两个数据集的相对大小,可以考虑以下几种图表类型:
- 折线图:直接显示两个数据集的值,便于比较。
- 并列柱状图:将两个数据集并排放置,便于比较每一个数据点。
- 双Y轴图:使用两个不同的Y轴来显示两个数据集,避免视觉上的干扰。
以下是使用并列柱状图和双Y轴图的示例:
并列柱状图
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.style as psl
# 魔法命令,用于在笔记本内联显示matplotlib图表
%matplotlib inline
# 确保图表以SVG格式显示
%config InlineBackend.figure_format = 'svg'
psl.use('ggplot')
# 设置随机种子以保证可重复性
np.random.seed(42)
# 导入数据
df = pd.DataFrame(data={'日期': pd.date_range('20231101', periods=30),
'进货价格': np.random.randint(low=100, high=1000, size=30),
'实际售价': np.random.randint(low=100, high=1000, size=30)}
)
# 绘制并列柱状图
df.plot(kind='bar', x='日期', figsize=(12, 6))
plt.title('进货价格与实际售价对比 - 并列柱状图')
plt.xlabel('日期')
plt.ylabel('价格')
plt.xticks(rotation=45)
plt.legend(loc='best')
plt.show()
双Y轴图
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.style as psl
# 魔法命令,用于在笔记本内联显示matplotlib图表
%matplotlib inline
# 确保图表以SVG格式显示
%config InlineBackend.figure_format = 'svg'
psl.use('ggplot')
# 设置随机种子以保证可重复性
np.random.seed(42)
# 导入数据
df = pd.DataFrame(data={'日期': pd.date_range('20231101', periods=30),
'进货价格': np.random.randint(low=100, high=1000, size=30),
'实际售价': np.random.randint(low=100, high=1000, size=30)}
)
fig, ax1 = plt.subplots(figsize=(12, 6))
ax1.plot(df['日期'], df['进货价格'], color='b', label='进货价格')
ax1.set_xlabel('日期')
ax1.set_ylabel('进货价格', color='b')
ax1.tick_params(axis='y', labelcolor='b')
ax1.legend(loc='upper left')
ax2 = ax1.twinx()
ax2.plot(df['日期'], df['实际售价'], color='r', label='实际售价')
ax2.set_ylabel('实际售价', color='r')
ax2.tick_params(axis='y', labelcolor='r')
ax2.legend(loc='upper right')
plt.title('进货价格与实际售价对比 - 双Y轴图')
fig.tight_layout()
plt.xticks(rotation=45)
plt.show()
通过这些图表,你可以更清晰地比较两个数据集的相对大小和变化趋势。
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt # 导入matplotlib包
import matplotlib.style as psl
# 魔法命令,用于在笔记本内联显示matplotlib图表
%matplotlib inline
# 确保图表以SVG格式显示
%config InlineBackend.figure_format = 'svg'
psl.use('ggplot')
plt.figure(figsize=(9, 6)) # 设置图表画布大小
# 设置随机种子以保证可重复性
np.random.seed(42)
# 导入数据
df = pd.DataFrame(data={'日期': pd.date_range('20231101', periods=30),
'进货价格': np.random.randint(low=100, high=1000, size=30),
'实际售价': np.random.randint(low=100, high=1000, size=30)}
)
# 检查生成的数据
print(df)
# 绘制折线图以比较数据
df.set_index('日期').plot(figsize=(9, 6)) # 使用日期作为索引
plt.title('进货价格与实际售价对比')
plt.xlabel('日期')
plt.ylabel('价格')
plt.xticks(rotation=45)
plt.legend(loc='best')
plt.show()
日期 进货价格 实际售价
0 2023-11-01 202 260
1 2023-11-02 535 559
2 2023-11-03 960 413
3 2023-11-04 370 121
4 2023-11-05 206 352
5 2023-11-06 171 847
6 2023-11-07 800 956
7 2023-11-08 120 660
8 2023-11-09 714 574
9 2023-11-10 221 158
10 2023-11-11 566 610
11 2023-11-12 314 781
12 2023-11-13 430 575
13 2023-11-14 558 799
14 2023-11-15 187 882
15 2023-11-16 472 289
16 2023-11-17 199 786
17 2023-11-18 971 662
18 2023-11-19 763 975
19 2023-11-20 230 666
20 2023-11-21 761 343
21 2023-11-22 408 931
22 2023-11-23 869 604
23 2023-11-24 443 230
24 2023-11-25 591 584
25 2023-11-26 513 918
26 2023-11-27 905 746
27 2023-11-28 485 120
28 2023-11-29 291 940
29 2023-11-30 376 266
<Figure size 900x600 with 0 Axes>
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.style as psl
# 魔法命令,用于在笔记本内联显示matplotlib图表
%matplotlib inline
# 确保图表以SVG格式显示
%config InlineBackend.figure_format = 'svg'
psl.use('ggplot')
# 设置随机种子以保证可重复性
np.random.seed(42)
# 导入数据
df = pd.DataFrame(data={'日期': pd.date_range('20231101', periods=30),
'进货价格': np.random.randint(low=100, high=1000, size=30),
'实际售价': np.random.randint(low=100, high=1000, size=30)}
)
# 绘制并列柱状图
df.plot(kind='bar', x='日期', figsize=(12, 6))
plt.title('进货价格与实际售价对比 - 并列柱状图')
plt.xlabel('日期')
plt.ylabel('价格')
plt.xticks(rotation=45)
plt.legend(loc='best')
plt.show()
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.style as psl
# 魔法命令,用于在笔记本内联显示matplotlib图表
%matplotlib inline
# 确保图表以SVG格式显示
%config InlineBackend.figure_format = 'svg'
psl.use('ggplot')
# 设置随机种子以保证可重复性
np.random.seed(42)
# 导入数据
df = pd.DataFrame(data={'日期': pd.date_range('20231101', periods=30),
'进货价格': np.random.randint(low=100, high=1000, size=30),
'实际售价': np.random.randint(low=100, high=1000, size=30)}
)
fig, ax1 = plt.subplots(figsize=(12, 6))
ax1.plot(df['日期'], df['进货价格'], color='b', label='进货价格')
ax1.set_xlabel('日期')
ax1.set_ylabel('进货价格', color='b')
ax1.tick_params(axis='y', labelcolor='b')
ax1.legend(loc='upper left')
ax2 = ax1.twinx()
ax2.plot(df['日期'], df['实际售价'], color='r', label='实际售价')
ax2.set_ylabel('实际售价', color='r')
ax2.tick_params(axis='y', labelcolor='r')
ax2.legend(loc='upper right')
plt.title('进货价格与实际售价对比 - 双Y轴图')
fig.tight_layout()
plt.xticks(rotation=45)
plt.show()
4.气泡图
气泡图是一种多变量的数据可视化图表,它是散点图的一种变体。气泡图在原有的横纵坐标的基础上,引入第三个变量,用气泡的大小来表示。
**plt.scatter():**用于绘制散点图。
函数签名
plt.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:浮点数组类型,表示散点图的横坐标和纵坐标。长度必须相同。
- s:浮点数或浮点数组,表示点的大小。默认为 None。
- c:颜色或颜色序列,表示点的颜色。可以是颜色名称、RGB 元组、十六进制颜色字符串等。默认为 None。
- marker:标记样式,表示点的形状。可以是预定义的标记样式字符串,也可以是路径对象。默认为 None。
- cmap:Colormap 对象,用于将 c 映射为颜色。默认为 None。
- norm:标准化对象,用于将数据值映射到 0 到 1 的范围内,以在色彩映射中使用。默认为 None。
- vmin, vmax:浮点数,用于指定色彩映射的数据值的范围。默认为 None。
- alpha:浮点数,表示点的透明度。0 表示完全透明,1 表示不透明。默认为 None。
- linewidths:浮点数或浮点数组,表示点边缘的线宽。默认为 None。
- verts:用于绘制标记的顶点列表。仅当 marker 为 None 时使用。默认为 None。
- edgecolors:颜色或颜色序列,表示点边缘的颜色。默认为 None。
- data:可索引对象,可以与散点图中的点关联数据。这是使用面向对象绘图时的参数。默认为 None。
- **kwargs:其他可选参数,如线型、线宽等,可以通过关键字参数传递。这些参数将被应用于散点的标记样式。
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt # 导入matplotlib包
import matplotlib.style as psl
# 魔法命令,用于在笔记本内联显示matplotlib图表
%matplotlib inline
# 确保图表以SVG格式显示
%config InlineBackend.figure_format = 'svg'
psl.use('ggplot')
plt.figure(figsize=(9, 6)) # 设置图表画布大小
#导入数据
df=pd.DataFrame(data={'日期': pd.date_range('20231101',periods=30),
'销售数': np.random.randint(low=100,high=1000,size=30),
'销售额': np.random.randint(low=1000,high=10000,size=30)}
)
x=df['销售数'].cumsum()
y=df['销售额'].cumsum()
#绘制气泡图
plt.scatter(x,y,marker="o",s =y/200,c=y*8000)
#设置标题
plt.title("双11销售数与销量额关系图",loc="center")
#添加数据标签
for a,b in zip(x,y):
plt.text(a,b,f'{b/10000:.1f}万',ha="center",va="center",fontsize=7,color="k")
#设置x和y轴名称
plt.xlabel("销售数/个")
plt.ylabel("销售额/万")
#图像展示
plt.show()
⏳跟练题目2
✍跟练2:假如你是一名电商销售分析人员,面临一项重要任务:深入研究销售数与销售额之间的关系。为了直观地揭示这两个变量之间的内在关联,你需要设计一个气泡图,用来揭示销售数与销售额之间的关系,使用下面的数据来模拟这种关系,其中,x为销售数据,y为销售额。
- x = np.random.rand(25) * 10
- y = np.random.rand(25) * 10
- z = np.random.rand(25) * 300 # 这将用于气泡的大小
💡 提示:plt.scatter(x, y, s=z)做气泡图,其中参数s用于指定气泡的大小,做出来的图表应与下面的图表类似
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt # 导入matplotlib包
import matplotlib.style as psl
# 魔法命令,用于在笔记本内联显示matplotlib图表
%matplotlib inline
# 确保图表以SVG格式显示
%config InlineBackend.figure_format = 'svg'
psl.use('ggplot')
plt.figure(figsize=(9, 6)) # 设置图表画布大小
#导入数据
x = np.random.rand(25) * 10
y = np.random.rand(25) * 10
z = np.random.rand(25) * 500 # 这将用于气泡的大小
#绘制气泡图
plt.scatter(x,y,marker="o",s =z,color='blue')
#设置标题
plt.title("气泡图",loc="center")
#添加数据标签
# for a,b in zip(x,y):
# plt.text(a,b,f'{b:.1f}万',ha="center",va="center",fontsize=10,color="k")
#设置x和y轴名称
plt.xlabel("X轴")
plt.ylabel("Y轴")
# 设置背景颜色为白色并移除网格线
plt.gca().set_facecolor('white')
plt.grid(False)
#图像展示
plt.show()
5.雷达图
雷达图也称为蜘蛛图、星图或极坐标图,是一种可视化图表。它以一个中心点为起点,从中心点向外延伸出多条射线,每条射线代表一个特定的变量或指标。连接各个坐标轴上的数据点形成的线条或多边形,可以表示某个对象在各个变量上的表现情况。
**plt.polar():**用于创建极坐标图。
函数签名
plt.polar(*args, **kwargs)
参数解释
- *args:此参数用于传递极坐标角度(以度为单位)和半径的数据。这些参数可以按顺序传递多个数据集,以在极坐标图上绘制多个曲线;
- **kwargs:其他关键字参数,用于控制图形的外观和属性。这些参数类似于 plt.plot() 函数的参数。
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt # 导入matplotlib包
import matplotlib.style as psl
# 魔法命令,用于在笔记本内联显示matplotlib图表
%matplotlib inline
# 确保图表以SVG格式显示
%config InlineBackend.figure_format = 'svg'
psl.use('ggplot')
plt.figure(figsize=(9, 6)) # 设置图表画布大小
# 假设df已经定义并包含正确的数据
df=pd.DataFrame(data={'区域':['华东','华北','东北','西北','西南','华南'],
'销售额': np.random.randint(low=10000,high=100000,size=6)}
)
labels = df['区域'].tolist()
sales = df['销售额'].tolist()
# 计算角度
N = len(labels)
angles = [n / float(N) * 2 * np.pi for n in range(N)]
# 保证雷达图是闭环
sales = np.concatenate((sales, [sales[0]]))
angles = np.concatenate((angles, [angles[0]]))
# 创建图形和子图
fig, ax = plt.subplots(figsize=(9, 6), subplot_kw=dict(polar=True))
# 绘制雷达图
ax.plot(angles, sales, 'r', linewidth=1)
ax.fill(angles, sales, 'r', alpha=0.3)
# 添加区域标签
for label, angle in zip(labels, angles[:-1]):
ax.text(angle, sales[0] + 0.3, label, ha='center', va='center')
# 添加销售额数据标签
for angle, sale in zip(angles, sales):
ax.text(angle, sale + 1000, f'{sale / 10000:.1f}万', ha='center')
# 隐藏角度标签
ax.set_xticklabels([])
ax.set_yticklabels([])
plt.title("各个区域的销售能力雷达图")
plt.show()
<Figure size 900x600 with 0 Axes>
重点代码解析:
解析这段代码,我们可以从以下几个步骤来逐步了解从计算角度到绘制雷达图的过程:
提取标签和数据
labels = df['区域'].tolist()
sales = df['销售额'].tolist()
- 提取区域标签和销售额数据。
计算角度
N = len(labels)
angles = [n / float(N) * 2 * np.pi for n in range(N)]
- 计算每个区域对应的角度。雷达图需要将圆等分成与标签数量相等的部分,每个部分的角度是
n / float(N) * 2 * np.pi
。
保证雷达图闭环
sales = np.concatenate((sales, [sales[0]]))
angles = np.concatenate((angles, [angles[0]]))
- 将第一个数据点添加到最后,确保雷达图是一个闭环。
创建图形和子图
fig, ax = plt.subplots(figsize=(9, 6), subplot_kw=dict(polar=True))
- 创建一个极坐标子图用于绘制雷达图。
绘制雷达图
ax.plot(angles, sales, 'r', linewidth=1)
ax.fill(angles, sales, 'r', alpha=0.3)
ax.plot
绘制雷达图的边界线。ax.fill
填充雷达图内区域。
添加区域标签
for label, angle in zip(labels, angles[:-1]):
ax.text(angle, sales[0] + 0.3, label, ha='center', va='center')
- 在对应的角度位置添加区域标签。
添加销售额数据标签
for angle, sale in zip(angles, sales):
ax.text(angle, sale + 1000, f'{sale / 10000:.1f}万', ha='center')
- 在对应的数据点位置添加销售额数据标签。
隐藏角度和径向标签
ax.set_xticklabels([])
ax.set_yticklabels([])
- 隐藏角度和径向标签,使图表更加简洁。
二、Matplotlib组合图表
1.组合图表
Matplotlib提供的组合图表功能在数据分析与可视化方面具备重要的应用价值。特别地,在组合图表中,将折线图与折线图、柱形图与折线图进行组合是两种常见且实用的形式。使得经管专业的学习者能够更加全面、有效地展示和分析数据,为他们的学习和研究工作提供有力的支持。
通过将两个或多个折线图组合在一起,我们可以在同一张图表中展示不同数据集或变量的趋势和变化,从而更方便地进行对比和分析。这对于经管领域的学习者来说,可以帮助他们更好地观察和理解数据之间的关联性,进而做出准确的推断和决策。
另外,柱形图与折线图的组合也是一种常用的图表形式。柱形图可以直观地展示不同类别的数据,而折线图则能够展示这些类别在时间序列上的变化趋势。这种组合图表的形式可以使学习者在一张图中同时观察到数据的分布和变化情况,提升他们对数据的综合分析能力。
1.1折线图+折线图
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt # 导入matplotlib包
import matplotlib.style as psl
# 魔法命令,用于在笔记本内联显示matplotlib图表
%matplotlib inline
# 确保图表以SVG格式显示
%config InlineBackend.figure_format = 'svg'
psl.use('ggplot')
plt.figure(figsize=(9, 6)) # 设置图表画布大小
#导入数据
df=pd.DataFrame(data={'日期': pd.date_range('20231101',periods=30),
'进货价格': np.random.randint(low=100,high=500,size=30),
'实际售价': np.random.randint(low=100,high=500,size=30)}
)
x=df['日期'].astype('str').tolist()
y1=df['进货价格'].tolist()
y2=df['实际售价'].tolist()
#绘制双折线绘图
plt.plot(x,y1,color="gray",linestyle="--",linewidth=1,marker="o",markersize=3,label ="进货价格")
plt.plot(x,y2,color="r",linestyle="solid",linewidth=1,marker="o",markersize=3,label="实际售价")
#设置标题
plt.title("双十一进货价格与实际售价组合图",loc="center")
#添加数据标签
for a,b in zip(x,y1):
plt.text(a, b, f'{b}元', ha = "center", va = "bottom", fontsize = 11)
for a,b in zip(x,y2):
plt.text(a, b, f'{b}元', ha = "center", va = "bottom", fontsize = 11)
#设置x和y轴的名称
plt.xlabel("日期")
plt.ylabel("价格")
#设置X坐标轴刻度
plt.xticks(x, ['{}日'.format(i+1) for i in range(30)],rotation=45)
#设置图例
plt.legend(loc = "upper right",frameon=False)
#图像展示
plt.show()
1.2柱形图+折线图
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt # 导入matplotlib包
import matplotlib.style as psl
# 魔法命令,用于在笔记本内联显示matplotlib图表
%matplotlib inline
# 确保图表以SVG格式显示
%config InlineBackend.figure_format = 'svg'
psl.use('ggplot')
plt.figure(figsize=(9, 6)) # 设置图表画布大小
#导入数据
df=pd.DataFrame(data={'日期': pd.date_range('20231101',periods=30),
'销售数': np.random.randint(low=1000,high=1500,size=30),
'销售额': np.random.randint(low=1500,high=7500,size=30)}
)
x=df['日期'].astype('str').tolist()
y1=df['销售数'].tolist()
y2=df['销售额'].tolist()
#绘制双折线绘图
plt.bar(x,y1,color="gray",label="销售数")
plt.plot(x,y2,color="r",linestyle="--",linewidth=1,marker="o",markersize=3,label ="销售额")
#设置标题
plt.title("双十一销售数与销售额组合图",loc="center")
#添加数据标签
for a,b in zip(x,y1):
plt.text(a, b, f'{b}单', ha = "center", va = "bottom", fontsize = 11)
for a,b in zip(x,y2):
plt.text(a, b, f'{b/10000:.1f}万', ha = "center", va = "bottom", fontsize = 11)
#设置x和y轴的名称
plt.xlabel("日期")
plt.ylabel("销售数/销售额")
#设置X坐标轴刻度
plt.xticks(x, ['{}日'.format(i+1) for i in range(30)],rotation=45)
#设置图例
plt.legend(loc = "upper right",frameon=False)
#图像展示
plt.show()
2.建立坐标系
当使用Matplotlib进行图表创建时,建立坐标系是必不可少的一步。Matplotlib提供了多种方式来建立坐标系,以便更好地组织和展示数据。其中,常用的四种建立坐标系的方式包括plt.subplot2grid建系、plt.subplot建系、plt.subplots建系以及add_subplot建系。这四种建立坐标系的方式在Matplotlib中都是常用且有效的,经管专业的学习者可以根据具体需求选择适合的方式来建立坐标系,以便更好地展示和解读数据。掌握这些建系方式对于经管领域的数据可视化分析将起到重要的作用。
2.1plt.subplot2gird建系
使用plt.subplot2grid建系方式,可以将画布划分为网格,并在指定的网格位置上创建坐标系,这种方式能够灵活地控制多个子图的位置和布局。
import numpy as np
import matplotlib.pyplot as plt # 导入matplotlib包
import matplotlib.style as psl
# 魔法命令,用于在笔记本内联显示matplotlib图表
%matplotlib inline
# 确保图表以SVG格式显示
%config InlineBackend.figure_format = 'svg'
psl.use('ggplot')
plt.figure(figsize=(9, 6)) # 设置图表画布大小
x = np.arange(30)
y = np.random.randint(low=0,high=100,size=30)
plt.figure(figsize=(9, 6)) #设置图表画布大小
#划分为2×2坐标系
plt.subplot2grid((2,2),(0,0))#在(0,0)的位置做折线图
plt.plot(x, y)
plt.subplot2grid((2,2),(0,1))#在(0,1)的位置做柱形图
plt.scatter(x, y)
plt.subplot2grid((2,2),(1,0))#在(0,1)的位置做柱形图
plt.barh(x, y)
plt.subplot2grid((2,2),(1,1))#在(0,1)的位置做柱形图
plt.bar(x, y)
plt.suptitle("subplot2gird多子图")
plt.show()
<Figure size 900x600 with 0 Axes>
2.2plt.subplot建系
plt.subplot建系方式允许直接指定子图的行列索引位置来创建坐标系,适用于较为简单的图表布局需求。
import numpy as np
import matplotlib.pyplot as plt # 导入matplotlib包
import matplotlib.style as psl
# 魔法命令,用于在笔记本内联显示matplotlib图表
%matplotlib inline
# 确保图表以SVG格式显示
%config InlineBackend.figure_format = 'svg'
psl.use('ggplot')
plt.figure(figsize=(9, 6)) # 设置图表画布大小
x = np.arange(30)
y = np.random.randint(low=0,high=100,size=30)
plt.figure(figsize=(9, 6)) #设置图表画布大小
plt.subplot(2,2,1)
plt.plot(x, y)
plt.subplot(2,2,2)
plt.scatter(x, y)
plt.subplot(2,2,3)
plt.barh(x, y)
plt.subplot(2,2,4)
plt.bar(x, y)
plt.suptitle("subplot多子图")
plt.show()
<Figure size 900x600 with 0 Axes>
⏳跟练题目3
✍跟练3:假如你是一名电商销售分析人员,需用plt.subplot()函数制作一个九宫格图来展示销售额情况,如果某个子图显示某一类产品的销售额异常,你可以进一步研究该产品的特点和市场表现,以发掘更多的增长机会,根据以上的业务需求,请实现你的九宫格子图创建。
💡 提示:如plt.subplot(3,3,1)可做3X3九宫格第一个子图,plt.subplots_adjust(wspace=0.25,hspace=0.5)可设置各个子图之前的间隙距离,做出来的图表应与下面的图表类似
2.3plt.subplots建系
通过plt.subplots建系方式,可以创建一个带有多个子图的坐标系,这种方式可以方便地管理轴标签、图例等共享元素,并确保它们在整个图形中的一致性。
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt # 导入matplotlib包
import matplotlib.style as psl
# 魔法命令,用于在笔记本内联显示matplotlib图表
%matplotlib inline
# 确保图表以SVG格式显示
%config InlineBackend.figure_format = 'svg'
psl.use('ggplot')
plt.figure(figsize=(9, 6)) # 设置图表画布大小
x = np.arange(30)
y = np.random.randint(low=0,high=100,size=30)
#绘制一个2×2的坐标系
fig, axes = plt.subplots(nrows=2,ncols=2,figsize = (9, 6))
axes[0,0].plot(x, y)
axes[0,1].scatter(x, y)
axes[1,0].barh(x, y)
axes[1,1].bar(x, y)
plt.suptitle("subplots多子图")
plt.show()
<Figure size 900x600 with 0 Axes>
2.4add_subplot建系
add_subplot建系方式则可以在已有的图形对象上添加新的子图,对于需要在已有图表上叠加多个图层或子图的情况较为适用。
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt # 导入matplotlib包
import matplotlib.style as psl
# 魔法命令,用于在笔记本内联显示matplotlib图表
%matplotlib inline
# 确保图表以SVG格式显示
%config InlineBackend.figure_format = 'svg'
psl.use('ggplot')
plt.figure(figsize=(9, 6)) # 设置图表画布大小
x = np.arange(30)
y = np.random.randint(low=0,high=100,size=30)
#绘制一个2×2的坐标系
fig = plt.figure(figsize = (9, 6))
ax1 = fig.add_subplot(2,2,1)
ax1.plot(x, y)
ax2 = fig.add_subplot(2,2,2)
ax2.scatter(x, y)
ax3 = fig.add_subplot(2,2,3)
ax3.barh(x, y)
ax4 = fig.add_subplot(2,2,4)
ax4.bar(x, y)
plt.suptitle("add_subplot多子图")
plt.show()
<Figure size 900x600 with 0 Axes>
三、闯关题
STEP1: 按照要求计算下方题目结果
⛳️闯关题目:电商销售额数据波动分析
假如你是一家电商公司的数据分析师,想要更细致地分析近一个月(一共28天4周)的销售额数据。为了做这一分析,你需要使用pandas生成模拟的销售额数据,并使用matplotlib的plt.subplot功能将这一个月的销售额数据分为四周进行展示,直观上展示每一周的销售额的数据情况,分析哪一周的销售额波动最大。
💡题目提示:
- 使用pandas生成近一个月的电商销售额模拟数据。
- 将这一个月的数据分为四周。使用df[‘日期’].dt.week命令得出周数
- 使用plt.subplot制作四个子图,分别展示四周的销售额数据。可使用plt.subplot()命令分别绘图
- 每个子图需要清晰地展示出该周的销售额趋势。
请使用下面的代码生成近一个月(一共28天4周,周一为一周的第一天)销售额数据,并生成多子图,根据多子图判断和分析销售额的波动趋势。
import pandas as pd
# 生成一组销售额数据
sales_data =[5927, 6555, 4146, 3050, 5757, 6446, 6045,
7893, 6693, 9373, 9565, 8436, 7754, 5677,
8895, 8354, 9362, 8225, 7893, 9619, 8022,
10151, 13600, 17740, 16259, 12996, 14007, 18000]
# 创建一个DataFrame
df = pd.DataFrame(pd.date_range(start='2023-10-30', periods=28, freq='D'),
columns=['日期'])
df['销售额'] = sales_data
df
日期 | 销售额 | |
---|---|---|
0 | 2023-10-30 | 5927 |
1 | 2023-10-31 | 6555 |
2 | 2023-11-01 | 4146 |
3 | 2023-11-02 | 3050 |
4 | 2023-11-03 | 5757 |
5 | 2023-11-04 | 6446 |
6 | 2023-11-05 | 6045 |
7 | 2023-11-06 | 7893 |
8 | 2023-11-07 | 6693 |
9 | 2023-11-08 | 9373 |
10 | 2023-11-09 | 9565 |
11 | 2023-11-10 | 8436 |
12 | 2023-11-11 | 7754 |
13 | 2023-11-12 | 5677 |
14 | 2023-11-13 | 8895 |
15 | 2023-11-14 | 8354 |
16 | 2023-11-15 | 9362 |
17 | 2023-11-16 | 8225 |
18 | 2023-11-17 | 7893 |
19 | 2023-11-18 | 9619 |
20 | 2023-11-19 | 8022 |
21 | 2023-11-20 | 10151 |
22 | 2023-11-21 | 13600 |
23 | 2023-11-22 | 17740 |
24 | 2023-11-23 | 16259 |
25 | 2023-11-24 | 12996 |
26 | 2023-11-25 | 14007 |
27 | 2023-11-26 | 18000 |
# 下面这里写入你的代码
import pandas as pd
import matplotlib.pyplot as plt
# 生成一组销售额数据
sales_data =[5927, 6555, 4146, 3050, 5757, 6446, 6045,
7893, 6693, 9373, 9565, 8436, 7754, 5677,
8895, 8354, 9362, 8225, 7893, 9619, 8022,
10151, 13600, 17740, 16259, 12996, 14007, 18000]
# 创建一个DataFrame
df = pd.DataFrame(pd.date_range(start='2023-10-30', periods=28, freq='D'),
columns=['日期'])
df['销售额'] = sales_data
# 将数据按周分组
weeks = df.groupby(df['日期'].dt.isocalendar().week)
# 创建一个新的figure窗口
plt.figure(figsize=(9, 6))
# 定义子图的索引
subplot_index = 1
# 遍历每周的数据并绘制子图
for week, week_data in weeks:
plt.subplot(2, 2, subplot_index) # 使用plt.subplot(2, 2, index)形式创建子图
plt.plot(week_data['日期'], week_data['销售额'], marker='o', linestyle='-', color='r')
plt.title(f"Week{week}") # 设置子图标题
plt.xlabel('日期') # 设置x轴标题
plt.ylabel('销售额') # 设置y轴标题
plt.xticks(rotation=25) # 设置x轴刻度
plt.grid(True) # 显示网格线
subplot_index += 1 # 更新子图索引
plt.ylim(0,20000) # 设置y轴的最小值为0,从0开始显示
plt.tight_layout() # 调整子图之间的间距
plt.show() # 显示图表
q1:请根据做出来的图表分析销售额的波动趋势,哪一周的波动趋势最大?选择正确的选项,并把选项赋值给a1。
- A:Week44
- B:Week45
- C:Week46
- D:Week47
#请根据做出来的图表分析销售额的波动趋势,哪一周的波动趋势最大?
a1='D' #在=后填入销售额波动趋势最大的那周的选项,可选项:A:'Week44'、B:'Week45'、C:'Week46'、D:'Week47'
a1
'D'
q2:请根据做出来的图表分析销售额的波动趋势,销售额的峰值是多少?并把结果赋值给a2。
#请根据做出来的图表分析销售额的波动趋势,销售额的峰值是多少?
a2= 18000#在=后填入销售额峰值,填入具体数值如17000
a2
18000