线型图的绘制主要由plt.plot()函数完成。该函数的调用格式如下:
matplotlib.pyplot.plot(x,y,format_string,**kwargs)
参数说明如下:
参数 | 属性 | 描述 |
---|---|---|
x | 列表或数组,可选参数 | x轴数据 |
y | 列表或数组,必选参数 | y轴数据 |
format_string | 可选参数 | 控制曲线的格式字符串 |
在plt.plot()函数中x轴和y轴的数据也可以通过numpy传递参数。根据传递的参数,可以绘制单个或多个线条,可以是直线,也可以是曲线。format_string可以设置线性的风格与样式。
例1:绘制一个包含一条直线的直线线型图
import matplotlib.pyplot as plt
import numpy as np
x = np.arange(1,11)
y = 2*x + 5
# 设置图标样式
plt.title("Matplotlib Demo")
plt.xlabel("x axis caption")
plt.ylabel("y axis caption")
# 绘制图表
plt.plot(x,y,"oc")
# 展示图表
plt.show()
例2:绘制正弦图和余弦图
import matplotlib.pyplot as plt
import numpy as np
x = np.arange(0, 3*np.pi, 0.1)
y_sin = np.sin(x)
y_cos = np.cos(x)
# 建立subplot网格,高为 2,宽为1
# 激活第一个subplot,并绘制第一个图像
plt.subplot(2, 1, 1)
plt.plot(x, y_sin, "pm")
plt.title('Sine')
# 激活第二个subplot,并绘制第二个图像
plt.subplot(2, 1, 2)
plt.plot(x, y_cos, "*y")
plt.title('Cosine')
# 展示图表
plt.show()
例3:绘制x的一次幂、二次幂和三次幂曲线
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 10, 100)
plt.axis([0, 4, 0, 50])
plt.plot(x, x, label='linear')
plt.plot(x, x**2, label='quadratic')
plt.plot(x, x**3, label='cubic')
plt.xlabel('x label')
plt.ylabel('y label')
plt.title("Simple Plot")
plt.legend()
plt.show()
例4:绘制一个简单的折线图
from matplotlib import pyplot as plt
x = range(2,26,2)
y = [15,13,14,5,17,20,25,26,24,22,18,15]
plt.figure(figsize=(20,8),dpi=80) # figsize设置图片大小,dpi设置清晰度
plt.plot(x,y)
plt.xticks(x)
plt.yticks(range(min(y),max(y)+1)) # 最后一位取不到,所以要加1
plt.show()
例5:绘制气温变化折线图
import random
from matplotlib import pyplot as plt
import matplotlib
# 绘制气温变化
# matplotlib设置显示中文
matplotlib.rc("font",family='KaiTi',weight="bold")
x = range(0,120)
y = [random.randint(20,35) for i in range(120)]
plt.figure(figsize=(25,8),dpi=80)
plt.plot(x,y)
# 调整x轴的刻度
_x1 = list(x)
_xtick_labels = ["10点{}分".format(i) for i in range(60)]
_xtick_labels += ["11点{}分".format(i) for i in range(60)]
# 设置字符串作为x轴,要有数字和字符一一对应
plt.xticks(list(_x1)[::3],_xtick_labels[::3],rotation=45)
plt.xlabel("时间")
plt.ylabel("温度 单位(。c)")
plt.title("10点到12点每分钟的气温变化情况")
plt.show()
直方图(histogram)是一种可以对值的频率进行离散化显示的柱状图。数据点被拆分到离散的、间隔均匀的面元中,绘制的是各面元中数据点的数量。绘制直方图所需调用的函数格式如下:
matplotlib.pyplot.hist(
x, bins=10, range=None, normed=False,
weights=None, cumulative=False, bottom=None,
histtype=u'bar', align=u'mid', orientation=u'vertical',
rwidth=None, log=False, color=None, label=None, stacked=False,
hold=None, **kwargs)
参数说明如下:
参数 | 属性 | 意义 |
---|---|---|
x | 数组或数组列表 | 指定要绘制直方图的数据 |
bins | 整数值或列表 | 指定直方图条形的个数 |
range | 元组或None | 指定直方图数据的上下界,默认包含绘图数据的最大值和最小值 |
normed | 布尔类型,默认值为false | 是否将直方图的频数转换成频率,如果其值为true ,则返回的元组的第一个参数frequency将为频率 |
weights | 该参数可为每一个数据点设置权重,如果normed取值为true ,则会对权重进行归一化处理 |
|
cumulative | 布尔类型 | 是否需要计算累计频数或频率,如果normed取值为true ,则计算累计频率 |
bottom | 列表,标量值或None | 可以为直方图的每个条形添加基准线,默认为0 |
histtype | 默认为bar,除此之外,还有barstacked、step和stepfilled | 指定直方图的类型 |
align | 默认值为mid,另外还有left和right | 设置条形边界值的对齐方式 |
orientation | 默认为vertical,另外还有horizontal | 设置直方图的摆放方向 |
rwidth | 标量值或None | 设置直方图条形的宽度 |
log | 布尔类型 | 是否需要对绘图数据进行log变换 |
color | 颜色列表或None | 设置直方图的填充色 |
edgecolor | 设置直方图边框色 | |
label | 字符串列表或None | 设置直方图的标签,可通过legend展示其图例 |
stacked | 布尔类型,默认值为false | 当有多个数据时,是否需要将直方图呈堆叠摆放 |
当我们绘制多个数据集的直方图时,还可以以下面的方式调用hist
函数:
n, bins, patches = plt.hist(datasets, bins, normed=False, facecolor=None, alpha=None)
参数说明如下:
参数 | 属性 | 意义 |
---|---|---|
datasets | 数据集列表,datasets中各个数据集的长度可以不等,也可以传入numpy中的 2-D ndarray | |
bins | 整数值或列表 | 直方图中箱子(bin)的个数 |
facecolor | 颜色字符串 | 箱子的颜色 |
alpha | 浮点数 | 箱子的透明度 |
normed | 决定直方图y轴 取值是落在某个箱子中的元素的个数(normed=False或normed=0),还是某个箱子中的元素的个数占总体的百分比(normed=True或normed=1) |
函数返回值:返回值为一个元组(tuple)
直方图的主要作用是:
例1:绘制一个简单的直方图
from matplotlib import pyplot as plt, mlab
import matplotlib
font = {'family': 'MicroSoft YaHei'}
matplotlib.rc('font', **font) # 设置显示中文
a = [131, 98, 125, 131, 124, 139, 131, 117, 128, 108, 135, 138, 131, 102, 107, 114, 119, 128, 121, 142, 127, 130, 124, 101, 110, 116, 117, 110, 128, 128, 115, 99, 136, 126, 134, 95, 138, 117, 111, 78, 132, 124, 113, 150, 110, 117, 86, 95, 144, 105, 126, 130, 126, 130, 126, 116, 123, 106, 112, 138, 123, 86, 101, 99, 136, 123, 117, 119, 105, 137, 123, 128, 125, 104, 109, 134, 125, 127, 105, 120, 107, 129, 116, 108, 132, 103, 136, 118, 102, 120, 114, 105, 115, 132, 145, 119, 121, 112, 139, 125, 138, 109, 132, 134, 156, 106, 117, 127, 144, 139, 139, 119, 140, 83, 110, 102, 123, 107, 143, 115, 136, 118, 139, 123, 112, 118, 125, 109, 119, 133, 112, 114, 122, 109, 106, 123, 116, 131, 127, 115, 118, 112, 135, 115, 146, 137, 116, 103, 144, 83, 123, 111, 110, 111, 100, 154, 136, 100, 118, 119, 133, 134, 106, 129, 126, 110, 111, 109, 141, 120, 117, 106, 149, 122, 122, 110, 118, 127, 121, 114, 125, 126, 114, 140, 103, 130, 141, 117, 106, 114, 121, 114, 133, 137, 92, 121, 112, 146, 97, 137, 105, 98, 117, 112, 81, 97, 139, 113, 134, 106, 144, 110, 137, 137, 111, 104, 117, 100, 111, 101, 110, 105, 129, 137, 112, 120, 113, 133, 112, 83, 94, 146, 133, 101, 131, 116, 111, 84, 137, 115, 122, 106, 144, 109, 123, 116, 111, 111, 133, 150]
d = 3 # 计算组距
num_bins = (max(a) - min(a)) // d # 计算组距的公式
plt.figure(figsize=(20, 8), dpi=80)
plt.hist(a, num_bins) # 加上normed=True属性之后变为频率分布直方图
# 设置x轴的刻度
plt.xticks(range(min(a), max(a) + d, d))
plt.grid(alpha=0.3)
plt.show()
例2:绘制一个趋于正态分布的直方图
import numpy as np
from matplotlib import pyplot as plt
np.random.seed(20170617)
mu, sigma = 100, 15
x = mu + sigma * np.random.randn(10000)
fig, ax = plt.subplots()
p, bins, patches = plt.hist(x, 50, density=1, facecolor='g', alpha=0.75)
plt.show()
还有一种与此相关的图表是核密度图。它是通过计算“可能会产生观测数据的连续概率分布的估计”(也就是对数据的生成分布进行估计)。一般的过程是将该分布近似为一组核(即诸如正态分布之类的较为简单的分布),因此,密度图也被称为KDE(Kernel Density Estimate,核密度估计)。调用plot()时附加上kind='kde’即可生成一张密度图。
例3:绘制上图对应的正态分布曲线
import numpy as np
from matplotlib import pyplot as plt
np.random.seed(20170617)
mu, sigma = 100, 15
x = mu + sigma * np.random.randn(10000)
fig, ax = plt.subplots()
p, bins, patches = plt.hist(x, 50, density=1, facecolor='g', alpha=0.75)
# 绘制核密度曲线
y = ((1 / (np.sqrt(2 * np.pi) * sigma)) * np.exp(-0.5 * (1 / sigma * (bins - mu)) ** 2))
ax.plot(bins, y, '--')
plt.show()
例4:绘制一条关于体重的正态分布概率密度曲线,并标定正态分布概率密度的公式
import numpy as np
from matplotlib import pyplot as plt
import matplotlib
matplotlib.rcParams["font.sans-serif"] = ["KaiTi"]
matplotlib.rcParams["axes.unicode_minus"] = False
mu = 60.0
sigma = 2.0
x = mu + sigma * np.random.randn(500)
bins = 50
fig, ax = plt.subplots(1, 1)
n, bins, patches = ax.hist(x, bins, density=True, histtype="bar", facecolor="#99FF33", edgecolor="#00FF99", alpha=0.75)
y = ((1 / (np.power(2 * np.pi, 0.5) * sigma)) * np.exp(-0.5 * np.power((bins - mu) / sigma, 2)))
ax.plot(bins, y, color="#7744FF", ls="--", lw=2)
ax.grid(ls=":", lw=1, color="gray", alpha=0.2)
ax.text(54, 0.2, r"$y=\frac{1}{\sqrt{2\pi}\sigma}e^{-\frac{(x-\mu)^2}{2\sigma^2}}$",
{"color": "#FF5511", "fontsize": 20})
ax.set_xlabel("体重")
ax.set_ylabel("概率密度")
ax.set_title(r"体重的直方图:$\mu=60.0$, $\sigma=2.0$", fontsize=16)
plt.show()
相较散点图和折线图,柱状图(直方图、条形图)、饼图、箱线图是另外3种数据分析常用的图形,主要用于分析数据内部的分布状态或分散状态。柱状图(直方图、条形图)主要用于查看各分组数据的数量分布,以及各个分组数据之间的数量比较。条形图分为垂直条形图和水平条形图,绘制垂直条形图和水平条形图分别调用bar()函数和barh()函数,其调用的函数格式分别如下:
# 垂直条形图
matplotlib.pyplot.bar(x, height, width=0.8, bottom=None, *, align='center', data=None, **kwargs)
# 水平条形图
matplotlib.pyplot.barh(y, width, height=0.8, left=None, *, align='center', **kwargs)
参数说明如下:
参数 | 属性 | 意义 |
---|---|---|
x | 整数或浮点数 | 设置x轴坐标 |
height | 整数或浮点数组成的列表 | 设置条形图条带的高度 |
width | 0-1之间的浮点数,默认值为0.8 | 设置条形图条带的宽度 |
alpha | 数值 | 设置条形图条带的颜色透明度 |
bottom | 列表 | 设置条形图条带的起始位置 |
align | 字符串,可选值为“center”和“lege” | 设置条形图条带的中心位置 |
color | 颜色字符串,默认值为“b” | 设置条形图条带的颜色 |
edgecolor | 颜色字符串 | 设置条形图条带的边框颜色 |
linewidth | 整数数值 | 设置条形图条带的边框宽度 |
tick_label | 字符串列表 | 设置条形图下标的标签 |
log | 布尔类型 | |
orientation | 字符串,可选值为“vertical”和“horizontal” | 设置条形图条带的方向 |
水平条形图可以利用bar()函数绘制,也可以利用barh()函数绘制,当用bar()函数绘制时,orientation="horizontal"
,然后x与y的数据交换,再添加bottom=x
即可。
例1:绘制某园区苹果与橙子每个月的销售量
import numpy as np
import matplotlib.pyplot as plt
# 设置中文字体
plt.rcParams['font.sans-serif'] = ['SimHei']
apples = np.array([45, 46, 12, 45, 121, 65, 45, 60, 11, 56, 34, 54])
oranges = np.array([54, 36, 82, 47, 96, 34, 45, 62, 85, 66, 94, 63])
plt.figure('Bar Chart', facecolor='lightgray')
# 设置图标题
plt.title('Bar Chart', fontsize=16)
# 设置x、y轴标签名
plt.xlabel('Month', fontsize=14)
plt.ylabel('Volume', fontsize=14)
# 设施刻度字体大小
plt.tick_params(labelsize=10)
# 添加y轴上的网格
plt.grid(linestyle=':', axis='y')
# 生成柱状图
x = np.arange(12)
a = plt.bar(x-0.2, height=apples, width=0.4, color='dodgerblue', label='Apple', align='center')
b = plt.bar(x+0.2, height=oranges, width=0.4, color='orangered', label='Oranges', align='center')
# 给条带添加数据标签
for i in a + b:
h = i.get_height()
plt.text(i.get_x() + i.get_width() / 2, h, '%d' % int(h), ha='center', va='bottom')
# 设置x轴的刻度
plt.xticks(x, ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'])
# 设置图例
plt.legend()
plt.show()
例2:绘制一个试卷难度与试卷分数相关的水平柱状图
from matplotlib import pyplot as plt
import matplotlib as mpl
# 设置中文字体
mpl.rcParams["font.sans-serif"] = ["SimHei"]
mpl.rcParams["axes.unicode_minus"] = False
# 添加x轴与y轴的坐标值
x = [1,2,3,4,5]
y = [6,10,4,5,1]
# 生成柱状图
plt.barh(x,width=y,height=0.5,align="center",color="b",tick_label=["A","B","C","D","E"],alpha=0.6)
# 设置x、y轴标签名
plt.xlabel("测试难度")
plt.ylabel("试卷分数")
# 设置网格
plt.grid(True, axis="y",ls=":",color="r",alpha=0.3)
plt.show()
例3:绘制某两册图书每年销售数量的堆叠条形图
from matplotlib import pyplot as plt
import matplotlib as mpl
# 设置中文字体
mpl.rcParams['font.sans-serif'] = ['SimHei']
mpl.rcParams['axes.unicode_minus'] = False
label_list = ['2017', '2018', '2019', '2020']
num_list1 = [20, 30, 15, 35]
num_list2 = [15, 30, 40, 20]
# 生成条形图
x = range(len(num_list1))
y1 = plt.bar(x, height=num_list1, width=0.45, alpha=0.8, color='red', label="图书一")
y2 = plt.bar(x, height=num_list2, width=0.45, color='green', label="图书二", bottom=num_list1)
# 设置x、y轴标签名
plt.ylabel("数量")
plt.xlabel("年份")
# 设置图标题
plt.title("某两册图书每年销售数量")
# 设置x轴的标签
plt.xticks(x, label_list, rotation='horizontal')
# 设置y轴坐标界限
plt.ylim(0, 80)
# 设置图例
plt.legend()
plt.show()
例4:绘制某地区2015年和2017年的各年龄段人口组成条形图
from matplotlib import pyplot as plt
import matplotlib as mpl
import numpy as np
mpl.rcParams['font.sans-serif'] = ['SimHei']
x = np.array([8021, 7577, 7118, 7518, 10029, 12850, 10146, 9724, 11771, 12391, 10422, 7697,
7814, 5485, 3632, 2652, 1634, 721, 218, 44])
y = np.array([8292, 7685, 7371, 7192, 8883, 12223, 10798, 10020, 10646, 12802, 11745, 6533,
8259, 6257, 3956, 2737, 1785, 802, 238, 55])
plt.figure(figsize=(12,8))
plt.barh(range(len(y)), -x,color='darkorange',label='2015年')
plt.barh(range(len(x)), y,color='limegreen',label='2017年')
plt.xlim((-15000,15000))
plt.xticks((-15000,-10000,-5000,0,5000,10000,15000),('15000','10000','5000','0','5000','10000','15000'))
plt.yticks((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19),
('0-4岁', '5-9岁', '10-14岁', '15-19岁', '20-24岁', '25-29岁', '30-34岁', '35-39岁',
'40-44岁', '45-49岁', '50-54岁', '55-59岁', '60-64岁', '65-69岁', '70-74岁', '75-79岁',
'80-84岁', '85-89岁', '90-94岁', '95以上'))
plt.xlabel('人口数量(万)')
plt.legend()
plt.show()
例5:绘制一个外嵌条形图
from matplotlib import pyplot as plt
import numpy as np
import pandas as pd
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]]
columns = ('Freeze', 'Wind', 'Flood', 'Quake', 'Hail')
rows = ['%d year' % x for x in (100, 50, 20, 10, 5)]
df = pd.DataFrame(data,columns = ('Freeze', 'Wind', 'Flood', 'Quake', 'Hail'))
df.plot(kind='bar',grid = True,colormap='Blues_r',stacked=True,figsize=(8,3))
plt.table(cellText = data,
cellLoc='center',
cellColours = None,
rowLabels = rows,
rowColours = plt.cm.BuPu(np.linspace(0, 0.5,5))[::-1],
colLabels = columns,
colColours = plt.cm.Reds(np.linspace(0, 0.5,5))[::-1],
rowLoc='right',
loc='bottom')
plt.show()
绘制饼状图所需调用的函数格式如下:
matplotlib.pyplot.pie(x, explode=None, labels=None, colors=None, autopct=None,
pctdistance=0.6, shadow=False, labeldistance=1.1,
startangle=0, radius=1, counterclock=True, wedgeprops=None,
textprops=None, center=(0, 0), frame=False,
rotatelabels=False, *, normalize=None, data=None)
参数说明如下:
参数 | 属性 | 意义 |
---|---|---|
x | 指定绘图数据 | |
explode | 数值列表 | 设置饼状图每一部分到圆心的距离 |
labels | 字符串列表 | 设置饼状图各区域标签 |
colors | 颜色列表 | 设置饼状图各区域的颜色 |
autopct | 可选参数 | 控制显示百分比 |
pctdistance | 数值列表,可选参数 | 控制数据标签到圆心位置的距离 |
shadow | 布尔类型,可选参数 | 在饼图下面绘制阴影,显示出3D立体效果 |
labeldistance | 可选参数 | 设置饼图标签距中心的距离 |
startangle | 可选参数 | 设置旋转角度 |
radius | 可选参数 | 设置圆的半径 |
counterclock | 可选参数,默认为True ,即逆时针;将其改为False 即可改为顺时针 |
设置指针方向 |
wedgeprops | 字典类型,可选参数; | 参数字典传递给wedge对象用来画一个饼图 |
textprops | 字典类型,可选参数 | 设置标签和比例文字的格式 |
center | 浮点类型的列表,可选参数 | 设置图标中心位置 |
frame | 该参数为布尔类型,可选参数,默认值为False |
如果是true ,绘制带有表的轴框架 |
rotatelabels | 该参数为布尔类型,可选参数,默认为为False |
如果是true ,旋转每个label到指定的角度 |
例1:绘制一个一般饼状图
import matplotlib.pyplot as plt
plt.rcParams["font.family"] = "kaiti"
x = [32,29,15,8,7,9]
department = ["市场部","人事部","企划部","财务部","行政部","研发部"]
color_ls = ['r','c','g','b','m','y']
dist = [0,0,0.2,0,0,0]
plt.axes(aspect=1) # x、y轴均向增长,不设置会是椭圆形
plt.pie(x, labels=department, autopct="%.1f%%", colors=color_ls, explode=dist, shadow=True)
plt.title("部门管理比例", size=20)
plt.show()
例2:绘制一个嵌套饼状图
import matplotlib.pyplot as plt
plt.rcParams["font.family"] = "kaiti"
fig=plt.figure(figsize=(5,5),dpi=100)
x1=[7,22,14,5,14,6,32]
x2=[43,25,32]
inner_color=['#ffce2b','#00c5d2', '#ff812c']
outer_color=['#9ACD32','#836FFF','#1E90FF']
labels = ['标签1','标签2','标签3']
plt.pie(x1, autopct='%0.1f%%', radius=0.7, pctdistance=0.7,colors=inner_color,wedgeprops=dict(linewidth=3,width=0.4,edgecolor='w'))
plt.pie(x2, autopct='%0.1f%%', radius=1, pctdistance=0.8, colors=outer_color, wedgeprops=dict(linewidth=3,width=0.4,edgecolor='w'), labels=labels)
# 图例文字
legend_text=['子标签1','子标签2','子标签3']
# 设置图例标题、位置
plt.legend(legend_text, title='主题占比', loc='upper right', frameon=False, bbox_to_anchor=(0.75, 0, 0.4, 1))
#使饼图长宽相等,确保饼图被画成圆形
plt.axis('equal')
plt.show()
面积图又称区域图,强调数量随时间而变化的程度,也可用于引起人们对总值趋势的注意。堆积面积图和百分比堆积面积图还可以显示部分与整体的关系。在Matplotlib中绘制面积图有两种方式,一是调用stackplot
函数,二是使用Series.plot.area()
和DataFrame.plot.area()
创建面积图。下面我们现在了解一下第一种方法,并通过实例绘制一个简单的面积图。绘制面积图时stackplot
的函数调用格式如下:
matplotlib.pyplot.stackplot(x, *args, labels=(), colors=None, baseline='zero', data=None, **kwargs)
参数说明如下:
参数 | 属性 | 描述 |
---|---|---|
x | 列表 | 指定面积图的x轴数据 |
labels | 字符串列表 | 设置每一块面积图包含的标签 |
colors | 颜色列表 | 设置颜色填充面积图 |
baseline | 可选值有zero、sym、wiggle、weighted_wiggle |
设置面积图显示的基线位置 |
例1:绘制一个简单的面积图
import matplotlib.pyplot as plt
plt.figure(figsize=(9,6))
days = [1,2,3,4,5]
sleeping =[7,8,6,11,7]
eating = [2,3,4,3,2]
working =[7,8,7,2,2]
playing = [8,5,7,8,13]
plt.stackplot(days,sleeping,eating,working,playing, colors=['r','g','k','y'], baseline='sym')
plt.xlabel('x')
plt.ylabel('y')
plt.title('Stack Plot',fontsize = 18)
plt.legend(['Sleeping','Eating','Working','Playing'],fontsize = 18)
plt.show()
例2:下面我们再用上述第二种方式去绘制面积图:
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import matplotlib.style as psl
ts = pd.Series(np.random.randn(1000),index=pd.date_range('1/1/2010',periods=1000))
ts = ts.cumsum()
df = pd.DataFrame(np.random.randn(1000, 4), index = ts.index, columns=list('abcd'))
df = df.cumsum()
fig,axes = plt.subplots(2,1,figsize = (10,8))
df1 = pd.DataFrame(np.random.rand(10, 4), columns=['a', 'b', 'c', 'd'])
df2 = pd.DataFrame(np.random.randn(10, 4), columns=['a', 'b', 'c', 'd'])
df1.plot.area(colormap = 'Greens_r', alpha = 0.8, ax = axes[0])
df2.plot.area(stacked=False ,colormap = 'Set2',alpha=0.8, ax = axes[1])
plt.show()
fill_between()函数填充两条水平曲线之间的区域。曲线由点定义( x , y1 )和( x , y2 ). 这将创建一个或多个描述填充区域的多边形。绘制填图可以调用plt.fill()和plt.fill_between()函数,具体调用格式如下:
fill_between(
x, y1, y2=0, where=None, interpolate=False, step=None, *,
data=None, **kwargs)
参数说明如下:
参数 | 属性 | 描述 |
---|---|---|
x | 二维数组(长度n) | 定义曲线的节点的X坐标 |
y1 | 二维数组(长度n)或标量 | 定义第一条曲线的节点的Y坐标 |
y2 | 数组(长度N)或标量,默认值:0 | 定义第二条曲线的节点的Y坐标 |
where | 布尔数组(长度N),可选 | 用于判断某个区间内是否进行填充,如果判断为True,则进行填充,否则不填充 |
interpolate | 布尔值,默认值:False | |
step | 可选值为'pre'、'post'、'mid' |
|
**kwargs |
例3:绘制一个填图
from matplotlib import pyplot as plt
import numpy as np
fig,axes = plt.subplots(2,1,figsize = (8,6))
x = np.linspace(0, 1, 500)
y1 = np.sin(4 * np.pi * x) * np.exp(-5 * x)
y2 = -np.sin(4 * np.pi * x) * np.exp(-5 * x)
axes[0].fill(x, y1, 'r',alpha=0.5,label='y1')
axes[0].fill(x, y2, 'g',alpha=0.5,label='y2')
x = np.linspace(0, 5 * np.pi, 1000)
y1 = np.sin(x)
y2 = np.sin(2 * x)
axes[1].fill_between(x, y1, y2, color ='b',alpha=0.5,label='area')
for i in range(2):
axes[i].legend()
axes[i].grid()
plt.show()
什么是散点图?散点图是指在回归分析中,数据点在直角坐标系平面上的分布图,散点图表示因变量随自变量而变化的大致趋势,据此可以选择合适的函数对数据点进行拟合。用两组数据构成多个坐标点,考察坐标点的分布,判断两变量之间是否存在某种关联或总结坐标点的分布模式。散点图将序列显示为一组点。值由点在图表中的位置表示。类别由图表中的不同标记表示。散点图通常用于比较跨类别的聚合数据。绘制散点图所需调用的函数格式如下:
matplotlib.pyplot.scatter(
x, y, s=None, c=None, marker=None, cmap=None, norm=None,
vmin=None, vmax=None, alpha=None, linewidths=None,
verts=cbook.deprecation._deprecated_parameter,
edgecolors=None, *, plotnonfinite=False, data=None, **kwargs)
参数说明如下:
参数 | 属性 | 意义 |
---|---|---|
x、y | 形如shape(n,)的数组 | 设置散点的坐标 |
s | 形如shape(n,)的数组,可选参数,默认值为20 | 设置散点的面积 |
c | 颜色序列,可选参数,默认值为“b”(蓝色) | 设置散点的颜色 |
marker | 可选参数,默认值为“o” | 设置散点的标记 |
cmap | 可选参数 | colormap |
norm | 可选参数 | 调节数据亮度 |
vmin、vmax | 标量,可选参数 | 和norm配合使用用来归一化亮度数据 |
alpha | 标量,可选参数 | 设置散点的透明度 |
linewidths | 标量或数组,可选参数 | 设置散点的轮廓线宽 |
例1:绘制一个普通散点图
import matplotlib.pyplot as plt
x_coords = [0.13, 0.22, 0.39, 0.59, 0.68, 0.74,0.93]
y_coords = [0.75, 0.34, 0.44, 0.52, 0.80, 0.25,0.55]
fig = plt.figure(figsize = (8,5))
plt.scatter(x_coords, y_coords, marker = 's', s = 50)
for x, y in zip(x_coords, y_coords):
plt.annotate('(%s,%s)'%(x,y), xy = (x,y),xytext = (0, -10), textcoords = 'offset points',ha = 'center', va = 'top')
plt.xlim([0,1])
plt.ylim([0,1])
plt.show()
例2:绘制一个气泡图
import numpy as np
import matplotlib.pyplot as plt
fig=plt.figure(figsize=(8,6))
# Generating a Gaussion dataset: creating random vectors from the multivariate normal distribution
# given mean and covariance
mu_vec1=np.array([0,0])
cov_mat1=np.array([[1,0],[0,1]])
X=np.random.multivariate_normal(mu_vec1,cov_mat1,500)
R=X**2
R_sum=R.sum(axis=1)
plt.scatter(X[:,0],X[:,1],color='green',marker='o',s=32.*R_sum,edgecolor='black',alpha=0.5)
plt.show()
例3:绘制一个多组散点图
import numpy as np
import matplotlib.pyplot as plt
mu_vecl = np.array([0, 0])
cov_matl = np.array([[2,0],[0,2]])
x1_samples = np.random.multivariate_normal(mu_vecl, cov_matl,100)
x2_samples = np.random.multivariate_normal(mu_vecl+0.2, cov_matl +0.2, 100)
x3_samples = np.random.multivariate_normal(mu_vecl+0.4, cov_matl +0.4, 100)
plt.figure(figsize = (8, 6))
plt.scatter(x1_samples[:,0], x1_samples[:, 1], marker='x', color = 'blue', alpha=0.7, label = 'x1 samples')
plt.scatter(x2_samples[:,0], x1_samples[:,1], marker='o', color ='green', alpha=0.7, label = 'x2 samples')
plt.scatter(x3_samples[:,0], x1_samples[:,1], marker='^', color ='red', alpha=0.7, label = 'x3 samples')
plt.title('Multi-group scatter plot')
plt.ylabel('variable X')
plt.xlabel('Variable Y')
plt.legend(loc = 'upper right')
plt.show()
例4:绘制一个矩阵散点图
from matplotlib import pyplot as plt
import numpy as np
import pandas as pd
df = pd.DataFrame(np.random.randn(100,4),columns = ['a','b','c','d'])
pd.plotting.scatter_matrix(df,figsize=(10,6),
marker = 'o',
diagonal='kde',
alpha = 0.5,
range_padding=0.1)
plt.show()
热力图是以颜色区别或颜色深浅来反映地图上某一区域或图表中某一范围的特征,一般包括填充表格热力图和地图热力图。热力图的绘制主要是利用imshow()函数来完成,当然pcolor()函数也可以完成表格热力图的绘制,但适用性较低。调用imshow()函数的格式如下:
matplotlib.pyplot.imshow(
X, cmap=None, norm=None, aspect=None, interpolation=None,
alpha=None, vmin=None, vmax=None, origin=None, extent=None, *,
filternorm=True, filterrad=4.0, resample=None, url=None,
data=None, **kwargs)
主要参数说明如下:
参数 | 属性 | 描述 |
---|---|---|
X | 数组对象 | 可以使类似数组的对象,或者是PIL类型图像 |
cmap | 字符串或Colormap类型 | 用于将标量数据映射到颜色的Colormap 实例或已注册的Colormap 名称 |
norm | 在使用cmap 之前,用来将二维数组数据归一化到[0,1] |
|
interpolation | 默认值为nearest ,除此还有其他插值方法 |
设置插值方法 |
alpha | 浮点数,取值范围为[0,1] | 设置透明度 |
vmin、vmax | 当输入的是二维数组标量并且没有明确的norm 时,vmin 和vmax 定义colormap 覆盖的数据范围,默认情况下,colormap 覆盖所提供的值的完整范围数据 |
|
origin | 可选值为upper 和lower |
设置坐标轴的样式 |
参数interpolation
的可选值除了nearest
之外,还有none、bilinear、bicubic、spline16、spline36、hanning、hamming、hermite、kaiser、quadric、catrom、gaussian、bessel、mitchell、sinc、lanczos
。
例1:绘制一个简单的热力图
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import cm
data = np.random.uniform(0.5, 1.0, 100).reshape([10,10])
# 绘制热力图
plt.imshow(data, interpolation='nearest', cmap=cm.coolwarm, origin='lower')
# 设置颜色条
plt.colorbar(shrink=.92)
plt.xticks(())
plt.yticks(())
plt.show()
例2:绘制热力图
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import cm
column_labels = list('ABCD')
row_labels = list('WXYZ')
data = np.random.rand(4,4)
fig, ax = plt.subplots()
# 绘制热力图
heatmap = ax.pcolor(data, cmap=cm.Blues)
# 设置x轴和y轴的刻度位置
ax.set_xticks(np.arange(data.shape[0])+0.5, minor=False)
ax.set_yticks(np.arange(data.shape[1])+0.5, minor=False)
# 将y轴反向显示
ax.invert_yaxis()
# 将x轴的刻度和刻度标签移到坐标轴上面显示
ax.xaxis.tick_top()
# 设置x轴和y轴标签
ax.set_xticklabels(row_labels, minor=False)
ax.set_yticklabels(column_labels, minor=False)
plt.show()
例3:绘制热力图
import numpy as np
import matplotlib.pyplot as plt
vegetables = ["cucumber", "tomato", "lettuce", "asparagus", "potato", "wheat", "barley"]
farmers = ["Farmer Joe", "Upland Bros.", "Smith Gardening", "Agrifun", "Organiculture", "BioGoods Ltd.", "Cornylee Corp."]
#定义热力图数据
harvest = np.array([[0.8, 2.4, 2.5, 3.9, 0.0, 4.0, 0.0],
[2.4, 0.0, 4.0, 1.0, 2.7, 0.0, 0.0],
[1.1, 2.4, 0.8, 4.3, 1.9, 4.4, 0.0],
[0.6, 0.0, 0.3, 0.0, 3.1, 0.0, 0.0],
[0.7, 1.7, 0.6, 2.6, 2.2, 6.2, 0.0],
[1.3, 1.2, 0.0, 0.0, 0.0, 3.2, 5.1],
[0.1, 2.0, 0.0, 1.4, 0.0, 1.9, 6.3]])
# 将元组分解为fig和ax两个变量
fig, ax = plt.subplots()
# 显示图片
im = ax.imshow(harvest)
# 设置x轴与y轴刻度间隔
ax.set_xticks(np.arange(len(farmers)))
ax.set_yticks(np.arange(len(vegetables)))
# 设置x轴与y轴标签
ax.set_xticklabels(farmers)
ax.set_yticklabels(vegetables)
plt.setp(ax.get_xticklabels(), rotation=45, ha="right", rotation_mode="anchor")
for i in range(len(vegetables)):
for j in range(len(farmers)):
text = ax.text(j, i, harvest[i, j], ha="center", va="center", color="w")
# 设置图表标题
ax.set_title("Harvest of local farmers (in tons/year)")
fig.tight_layout() # 自动调整子图参数,使之填充整个图像区域
plt.show()
将上述例3封装成函数,自动生成热力图,代码如下:
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
def heatmap(data, row_labels, col_labels, ax=None, cbar_kw={}, cbarlabel="", **kwargs):
"""
从一个numpy数组和两个标签列表创建一个热图。
data:形状为(N,M)的2D numpy数组
row_labels:长度为N且带有行标签的列表或数组。
col_labels:长度为M的列表或数组,带有列的标签。
ax:绘制热图的`matplotlib.axes.Axes`实例。 如果未提供,请使用当前轴或创建一个新轴。 (可选的。)
cbar_kw:带有`matplotlib.Figure.colorbar`参数的字典。 可选的。
cbarlabel:颜色条的标签。 可选的。
**kwargs:所有其他参数都转发给“imshow”。
"""
# 如果不在ax,挪动坐标轴
if not ax:
ax = plt.gca()
im = ax.imshow(data, **kwargs)
# 创造彩条
cbar = ax.figure.colorbar(im, ax=ax, **cbar_kw)
"""
im:一个可以映射颜色的对象
ax=ax:指示im得到的对象在哪里展示(整体)
"""
"""设置y轴标签"""
cbar.ax.set_ylabel(cbarlabel, rotation=-90, va="bottom")
# 设置x,y轴刻度间隔
ax.set_xticks(np.arange(data.shape[1]))
ax.set_yticks(np.arange(data.shape[0]))
# 设置横,纵轴
ax.set_xticklabels(col_labels)
ax.set_yticklabels(row_labels)
# 让水平轴标签显示在顶部
ax.tick_params(top=True, bottom=False, labeltop=True, labelbottom=False)
# 旋转刻度线标签并设置其对齐方式。
plt.setp(ax.get_xticklabels(), rotation=-30, ha="right", rotation_mode="anchor")
# spines是连接轴刻度标记的线,而且标明了数据区域的边界,关闭spines并创建白色网格
for edge, spine in ax.spines.items():
spine.set_visible(False)
# 设置x,y轴刻度间隔
ax.set_xticks(np.arange(data.shape[1] + 1) - .5, minor=True)
ax.set_yticks(np.arange(data.shape[0] + 1) - .5, minor=True)
# 设置边框主刻度线,颜色为白色,线条格式为'-',线的宽度为3
ax.grid(which="minor", color="w", linestyle='-', linewidth=3)
# 设置主刻度线,参数bottom, top, left, right的值为布尔值,分别代表设置绘图区四个边框线上的的刻度线是否显示
ax.tick_params(which="minor", bottom=False, left=False)
return im, cbar
def annotate_heatmap(im, data=None, valfmt="{x:.2f}", textcolors=["black", "white"], threshold=None, **textkw):
"""
im:要标记的AxesImage。
data:用于注释的数据。如果为None,则使用图像数据。(可选的。)
valfmt:热图内注释的格式。这应该使用字符串格式方法,例如“${x:.2f}”,或成为`matplotlib.ticker.Formatter`。(可选的。)
textcolors:两种颜色规格的列表或数组。 第一个代表值低于阈值,第二个代表高于阈值的值。(可选的。)
threshold:以数据单位表示的值,根据该值,textcolors中的颜色是应用。如果为None(默认),则将颜色图的中间用作分离。( 可选的。)
**kwargs:所有其他参数都转发给用于创建的每个`text`调用。文字标签。
"""
# 保证data是一个list类型
if not isinstance(data, (list, np.ndarray)):
data = im.get_array()
# 将阈值标准化为图像颜色范围
if threshold is not None:
threshold = im.norm(threshold)
else:
threshold = im.norm(data.max()) / 2.
# 将默认对齐方式设置为居中,但允许将其设置为居中被textkw覆盖。
kw = dict(horizontalalignment="center",
verticalalignment="center")
kw.update(textkw)
# (如果提供了字符串)获取格式化程序
if isinstance(valfmt, str):
valfmt = matplotlib.ticker.StrMethodFormatter(valfmt)
# 给热力图标注文本设置格式
# 遍历数据并为每个“pixel”创建一个“Text”,根据数据更改文本的颜色。
texts = []
for i in range(data.shape[0]):
for j in range(data.shape[1]):
kw.update(color=textcolors[int(im.norm(data[i, j]) > threshold)])
text = im.axes.text(j, i, valfmt(data[i, j], None), **kw)
texts.append(text)
return texts
vegetables = ["cucumber", "tomato", "lettuce", "asparagus", "potato", "wheat", "barley"]
farmers = ["Farmer Joe", "Upland Bros.", "Smith Gardening", "Agrifun", "Organiculture", "BioGoods Ltd.", "Cornylee Corp."]
# 定义热力图数据
harvest = np.array([[0.8, 2.4, 2.5, 3.9, 0.0, 4.0, 0.0],
[2.4, 0.0, 4.0, 1.0, 2.7, 0.0, 0.0],
[1.1, 2.4, 0.8, 4.3, 1.9, 4.4, 0.0],
[0.6, 0.0, 0.3, 0.0, 3.1, 0.0, 0.0],
[0.7, 1.7, 0.6, 2.6, 2.2, 6.2, 0.0],
[1.3, 1.2, 0.0, 0.0, 0.0, 3.2, 5.1],
[0.1, 2.0, 0.0, 1.4, 0.0, 1.9, 6.3]])
fig, ax = plt.subplots()
im, cbar = heatmap(harvest, vegetables, farmers, ax=ax, cmap="YlGn", cbarlabel="harvest [t/year]")
texts = annotate_heatmap(im, valfmt="{x:.1f} t")
fig.tight_layout()
plt.show()
箱线图(Box-plot)又称为盒须图、盒式图或箱形图,是一种用作显示一组数据分散情况资料的统计图,因形状如箱子而得名。在各种领域也经常被使用,常见于品质管理。它主要用于反映原始数据分布的特征,还可以进行多组数据分布特征的比较。箱线图的绘制方法是:先找出一组数据的上边缘、下边缘、中位数和两个四分位数;然后, 连接两个四分位数画出箱体;再将上边缘和下边缘与箱体相连接,中位数在箱体中间。箱线图主要包含六个数据节点,将一组数据从大到小排列,分别计算出其上边缘(数据最大值),上四分位数Q3,中位数Q2,下四分位数Q1,下边缘(数据最小值),还有一个异常值。具体图示如下:
什么是分位数?分位数是将总体的全部数据按大小顺序排列后,处于各等分位置的变量值。如果将全部数据分成相等的两部分,它就是中位数;如果分成四等分,就是四分位数;八等分就是八分位数等。
例1:求数据的6, 47, 49, 15, 42, 41, 7, 39, 43, 40, 36(未排序)的Q1、Q2、Q3
首先排顺序,由小到大排列的结果: 6, 7, 15, 36, 39, 40, 41, 42, 43, 47, 49
位置计算:
Q1 的位置 = (11+1) × 0.25=3
Q2 的位置 = (11+1) × 0.5 =6
Q3 的位置 = (11+1) × 0.75=9
因此:Q1 = 15,Q2 = 40,Q3 = 43
例2:求数据: 15, 41, 7, 39, 40, 36(未排序)的Q1、Q2、Q3
首先排顺序,由小到大排列的结果: 6, 7, 15, 36, 39, 40, 41, 42, 43, 47, 49
位置计算:
Q1的位置 = (6+1) * 0.25 = 7/4 = 1.75,Q1在第一与第二个数字之间
Q2的位置 = (6+1) * 0.5 = 14/4 = 3.5, Q2在第三与第四个数字之间
Q3的位置 = (6+1) * 0.75 = 21/4 = 5.25,Q3在第五与第六个数字之间
位置 x 含有小数时计算方法,下图int(x)
表示取整:数a * (1 − x的小数部分) + 数b * x的小数部分
Q1 = 0.75 × 15 + 0.25 × 7 = 13
Q2 = ( 36 + 39 ) / 2 = 37.5
Q3 = 0.25 × 41 + 0.75 × 40 = 40.25
箱线图的绘制主要由plt.boxplot()函数完成。该函数的调用格式如下:
matplotlib.pyplot.boxplot(x, notch=None, sym=None, vert=None,
whis=None, positions=None, widths=None,
patch_artist=None, meanline=None, showmeans=None,
showcaps=None, showbox=None, showfliers=None,
boxprops=None, labels=None, flierprops=None,
medianprops=None, meanprops=None,
capprops=None, whiskerprops=None)
主要参数说明如下:
参数 | 属性 | 描述 |
---|---|---|
x | 数据列表 | 指定要绘制箱线图的数据 |
notch | 布尔类型 | 是否是凹口的形式展现箱线图,默认非凹口 |
sym | 字符串 | 指定异常点的形状,默认为+ 号显示 |
vert | 布尔类型 | 是否需要将箱线图垂直摆放,默认垂直摆放 |
whis | 整数数值 | 指定上下须与上下四分位的距离,默认为1.5倍的四分位差 |
positions | 列表 | 指定箱线图的位置,默认为[0,1,2…] |
widths | 浮点数 | 指定箱线图的宽度,默认为0.5 |
patch_artist | 布尔类型 | 是否填充箱体的颜色 |
meanline | 布尔类型 | 是否用线的形式表示均值,默认用点来表示 |
showmeans | 布尔类型 | 是否显示均值,默认不显示 |
showcaps | 布尔类型 | 是否显示箱线图顶端和末端的两条线,默认显示 |
showbox | 布尔类型 | 是否显示箱线图的箱体,默认显示 |
showfliers | 布尔类型 | 是否显示异常值,默认显示 |
boxprops | 字典类型 | 设置箱体的属性,如边框色,填充色等 |
labels | 为箱线图添加标签,类似于图例的作用 | |
flierprops | 字典类型 | 设置异常值的属性,如异常点的形状、大小、填充色等 |
medianprops | 字典类型 | 设置中位数的属性,如线的类型、粗细等 |
meanprops | 字典类型 | 设置均值的属性,如点的大小、颜色等 |
capprops | 字典类型 | 设置箱线图顶端和末端线条的属性,如颜色、粗细等 |
whiskerprops | 字典类型 | 设置须的属性,如颜色、粗细、线的类型等 |
例1:绘制一个简单的箱线图
from matplotlib import pyplot as plt
import numpy as np
x = np.linspace(0.05, 10, 50)
y = np.sin(x)
a = np.random.randn(100)
b = np.random.randn(100)
plt.boxplot([a, b, x, y], widths=0.2)
plt.show()
例2:绘制一个水平方向的箱线图
from matplotlib import pyplot as plt
import numpy as np
x = np.linspace(0.05, 10, 50)
y = np.sin(x)
a = np.random.randn(100)
b = np.random.randn(100)
plt.boxplot([a, b, x, y], notch = True, sym = 'b+', vert = 0, widths=0.3)
plt.show()
例3:绘制一个较为复杂的箱线图
from matplotlib import pyplot as plt
data = {'AQI':[183,240,325,133,61,55,75,130,161,139,157,155,233,155,85,113],
'PM 2.5':[140,190,281,100,42,37,55,98,122,104,115,143,190,60,80,72],
'PM 10':[220,297,286,82,47,34,68,127,164,145,175,230,237,38,84,70],
'So2':[88,74,36,26,24,20,28,47,52,39,47,86,42,34,31,33],
}
# Chart1
plt.subplot(1,4,1)
Box1=data["AQI"]
plt.grid(linestyle="--", alpha=0.3)
plt.boxplot(
Box1,
patch_artist=True,
showmeans=True, #显示均值点
whis=8,
widths=0.2, #箱体宽度
boxprops={'color': 'black', 'facecolor': '#FFDF00'}, #设置箱体属性
flierprops={'marker': 'o', 'mfc': 'red', 'color': 'black'}, #设置异常值属性
meanprops={'marker': '+', 'mfc': 'black'}, #设置均值点属性
medianprops={'ls': '--', 'color': 'orange'}, #设置中位数属性
whiskerprops={'ls': '--', 'mfc': 'red', 'color': 'black'}, #设置触须属性
)
plt.title('AQI')
plt.xticks([])
# Chart2
plt.subplot(1,4,2)
Box2=data["PM 2.5"]
plt.grid(linestyle="--", alpha=0.3)
plt.boxplot(
Box2,
patch_artist=True,
showmeans=True,
whis=8,
widths=0.2,
boxprops={'color': 'black', 'facecolor': '#2C4096'},
flierprops={'marker': 'o', 'mfc': 'red', 'color': 'black'},
meanprops={'marker': '+', 'mfc': 'black'},
medianprops={'ls': '--', 'color': 'orange'},
whiskerprops={'ls': '--', 'mfc': 'red', 'color': 'black'}
)
plt.title('MP 2.5')
plt.xticks([])
# Chart3
plt.subplot(1,4,3)
Box3=data["PM 10"]
plt.grid(linestyle="--", alpha=0.3)
plt.boxplot(Box3,
patch_artist=True,
showmeans=True,
whis=8,
widths=0.2,
boxprops={'color': 'black', 'facecolor': '#019000'},
flierprops={'marker': 'o', 'mfc': 'red', 'color': 'black'},
meanprops={'marker': '+', 'mfc': 'black'},
medianprops={'ls': '--', 'color': 'orange'},
whiskerprops={'ls': '--', 'mfc': 'red', 'color': 'black'}
)
plt.title('PM 10')
plt.xticks([])
# Chart4
plt.subplot(1,4,4)
Box4=data["So2"]
plt.grid(linestyle="--", alpha=0.3)
plt.boxplot( Box4,
patch_artist=True,
showmeans=True,
whis=8,
widths=0.2,
boxprops={'color': 'black', 'facecolor': '#D22C2C'},
flierprops={'marker': 'o', 'mfc': 'red', 'color': 'black'},
meanprops={'marker': '+', 'mfc': 'black'},
medianprops={'ls': '--', 'color': 'orange'},
whiskerprops={'ls': '--', 'mfc': 'red', 'color': 'black'}
)
plt.title('So2')
plt.xticks([])
# 添加总标题并显示图表
plt.suptitle('Box Plot')
plt.tight_layout(1.5)
plt.show()
雷达图是以从同一点开始的轴上表示的三个或更多个定量变量的二维图表的形式显示多变量数据的图形方法。轴的相对位置和角度通常是无信息的。 雷达图也称为网络图,蜘蛛图,星图,蜘蛛网图,不规则多边形,极坐标图或Kiviat图。它相当于平行坐标图,轴径向排列。
例1:绘制一个DOTA能力值雷达图
import numpy as np
import matplotlib.pyplot as plt
import matplotlib
matplotlib.rcParams["font.family"] = "SimHei"
matplotlib.rcParams["font.sans-serif"] = ["SimHei"]
# 构造雷达图标签和对应的数据
labels = np.array(["综合", "KDA", "发育", "推进", "生存", "输出"])
data = np.array([7, 5, 6, 9, 8, 7])
# 设置雷达图的角度,用于平分切开一个圆面
angles = np.linspace(0, 2 * np.pi, len(labels), endpoint=False)
# 将雷达图的标签,数据和角度封闭起来
labels = np.concatenate((labels, [labels[0]]))
data = np.concatenate((data, [data[0]]))
angles = np.concatenate((angles, [angles[0]]))
# 绘图
fig = plt.figure(facecolor="white")
plt.subplot(111, polar=True)
# 绘制折线图
plt.plot(angles, data, "bo-", color="g", linewidth=2)
# 填充颜色
plt.fill(angles, data, facecolor="g", alpha=0.25)
# 添加每个元素对应的标签
plt.thetagrids(angles * 180 / np.pi, labels)
plt.figtext(0.52, 0.95, "DOTA能力值雷达图", ha="center")
plt.grid(True)
plt.show()
例2:绘制一个反映某一品牌汽车的各项特征值的雷达图
import numpy as np
import matplotlib.pyplot as plt
import matplotlib
matplotlib.rcParams["font.family"] = "SimHei"
matplotlib.rcParams["font.sans-serif"] = ["SimHei"]
label = np.array(['耐撞', '加速', '集气', '转向', '喷射', '漂移'])
data = np.array([3.5, 4.5, 3.8, 5, 4, 4.5])
angles = np.linspace(0, 2 * np.pi, len(label), endpoint=False)
label = np.concatenate((label, [label[0]]))
data = np.concatenate((data, [data[0]]))
angles = np.concatenate((angles, [angles[0]]))
fig = plt.figure()
ax = fig.add_subplot(111, polar=True)
ax.plot(angles, data, 'bo', linewidth=2)
ax.fill(angles, data, facecolor='b', alpha=0.25)
ax.set_thetagrids(angles * 180 / np.pi, label)
# 设置雷达图的范围
ax.set_rlim(0, 5)
ax.grid(True)
plt.show()
例3:绘制一个反映影响某植物的生长因素的重要性的雷达图
import matplotlib.pyplot as plt
import matplotlib
from math import pi
import pandas as pd
matplotlib.rcParams["font.family"] = "SimHei"
matplotlib.rcParams["font.sans-serif"] = ["SimHei"]
df = pd.DataFrame({
'group': ['A', 'B', 'C', 'D'],
'光照': [38, 1.5, 30, 4],
'温度': [29, 10, 9, 34],
'降水': [8, 39, 23, 24],
'土壤': [7, 31, 33, 14],
'地形': [28, 15, 32, 14]
})
# 变量类别
categories = list(df)[1:]
# 变量类别个数
N = len(categories)
# 绘制数据的第一行
values = df.loc[0].drop('group').values.flatten().tolist()
# 将第一个值放到最后,以封闭图形
values += values[:1]
print(values)
# 设置每个点的角度值
angles = [n / float(N) * 2 * pi for n in range(N)]
angles += angles[:1]
# 初始化极坐标网格
ax = plt.subplot(111, polar=True)
# 设置x轴的标签
plt.xticks(angles[:-1], categories, color='grey', size=8)
# 设置标签显示位置
ax.set_rlabel_position(0)
# 设置y轴的标签
plt.yticks([10, 20, 30], ["10", "20", "30"], color="grey", size=7)
plt.ylim(0, 40)
# 画图
ax.plot(angles, values, linewidth=1, linestyle='solid')
# 填充区域
ax.fill(angles, values, 'b', alpha=0.1)
plt.show()
例4:绘制一个多变量雷达图
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = 'Microsoft YaHei'
plt.rcParams['axes.unicode_minus'] = False
plt.style.use('ggplot')
values = [3.2,2.1,3.5,2.8,3]
values2 = [4,4.1,4.5,4,4.1]
feature = ['个人能力','QC知识','解决问题能力','服务质量意识','团队精神']
N = len(values)
angles=np.linspace(0, 2*np.pi, N, endpoint=False)
values=np.concatenate((values,[values[0]]))
values2=np.concatenate((values2,[values2[0]]))
angles=np.concatenate((angles,[angles[0]]))
feature = np.concatenate((feature, [feature[0]]))
fig=plt.figure()
ax = fig.add_subplot(111, polar=True)
ax.plot(angles, values, 'o-', linewidth=2, label = '活动前')
ax.fill(angles, values, alpha=0.25)
ax.plot(angles, values2, 'o-', linewidth=2, label = '活动后')
ax.fill(angles, values2, alpha=0.25)
ax.set_thetagrids(angles * 180/np.pi, feature)
ax.set_ylim(0,5)
plt.title('活动前后员工状态表现')
ax.grid(True)
plt.legend(loc = 'lower right')
plt.show()
例5:绘制反映某两种植物生长相关因子的重要性的多变量雷达图
import matplotlib.pyplot as plt
from math import pi
import pandas as pd
plt.rcParams['font.sans-serif'] = 'Microsoft YaHei'
plt.rcParams['axes.unicode_minus'] = False
df = pd.DataFrame({
'group': ['A', 'B', 'C', 'D'],
'光照': [38, 1.5, 30, 4],
'温度': [29, 10, 9, 34],
'降水': [8, 39, 23, 24],
'土壤': [7, 31, 33, 14],
'地形': [28, 15, 32, 14]
})
categories = list(df)[1:]
N = len(categories)
angles = [n / float(N) * 2 * pi for n in range(N)]
angles += angles[:1]
ax = plt.subplot(111, polar=True)
ax.set_theta_offset(pi / 2)
ax.set_theta_direction(-1)
plt.xticks(angles[:-1], categories)
ax.set_rlabel_position(0)
plt.yticks([10, 20, 30], ["10", "20", "30"], color="grey", size=7)
plt.ylim(0, 40)
values = df.loc[0].drop('group').values.flatten().tolist()
values += values[:1]
ax.plot(angles, values, linewidth=1, linestyle='solid', label="group A")
ax.fill(angles, values, 'b', alpha=0.1)
values = df.loc[1].drop('group').values.flatten().tolist()
values += values[:1]
ax.plot(angles, values, linewidth=1, linestyle='solid', label="group B")
ax.fill(angles, values, 'r', alpha=0.1)
plt.legend(loc='upper right', bbox_to_anchor=(0.1, 0.1))
plt.show()
例6:绘制反映某四种植物生长相关因子的重要性的分面雷达图
import matplotlib.pyplot as plt
from math import pi
import pandas as pd
plt.rcParams['font.sans-serif'] = 'Microsoft YaHei'
plt.rcParams['axes.unicode_minus'] = False
df = pd.DataFrame({
'group': ['A', 'B', 'C', 'D'],
'光照': [38, 1.5, 30, 4],
'温度': [29, 10, 9, 34],
'降水': [8, 39, 23, 24],
'土壤': [7, 31, 33, 14],
'地形': [28, 15, 32, 14]
})
def make_spider(row, title, color):
categories = list(df)[1:]
N = len(categories)
angles = [n / float(N) * 2 * pi for n in range(N)]
angles += angles[:1]
ax = plt.subplot(2, 2, row + 1, polar=True, )
ax.set_theta_offset(pi / 2)
ax.set_theta_direction(-1)
plt.xticks(angles[:-1], categories, color='grey', size=8)
ax.set_rlabel_position(0)
plt.yticks([10, 20, 30], ["10", "20", "30"], color="grey", size=7)
plt.ylim(0, 40)
values = df.loc[row].drop('group').values.flatten().tolist()
values += values[:1]
ax.plot(angles, values, color=color, linewidth=2, linestyle='solid')
ax.fill(angles, values, color=color, alpha=0.4)
plt.title(title, size=8, loc='left', color=color, y=1.1)
my_dpi = 96
plt.figure(figsize=(1000 / my_dpi, 1000 / my_dpi), dpi=my_dpi)
my_palette = plt.cm.get_cmap("Set2", len(df.index))
for row in range(0, len(df.index)):
make_spider(row=row, title='group ' + df['group'][row], color=my_palette(row))
plt.tight_layout(2)
plt.show()
from matplotlib import pyplot as plt
import numpy as np
plt.figure(figsize=(8,4))
ax1= plt.subplot(111, projection='polar')
ax1.set_title('Rose Map\n')
ax1.set_rlim(0,12)
data = np.random.randint(1,10,10)
theta=np.arange(0,2*np.pi,2*np.pi/10)
bar = ax1.bar(theta,data,alpha=0.5)
for r,bar in zip(data, bar):
bar.set_facecolor(plt.cm.jet(r/10.))
plt.thetagrids(np.arange(0.0, 360.0, 90), [])
plt.show()