【导入md文档时格式不对,需要的可以下载juypter源文件拉通跑一次,太长了,推荐配合table of contents开启目录查看(文中配图太多了,手动随便加了几个,大多可以导入包和数据后自己跑下,调格式实在。。黑线脸)】
下载链接:https://download.csdn.net/download/qq_38611819/11240375
使用'%matplotlib inline':直接在笔记本中渲染图形(应该使用带有命令的内联后端),可以省略掉plt.show()这一步。
在Retina显示屏等高分辨率屏幕上,jupyter notebook电脑中的默认图像看起来很模糊。在%matplotlib inline后使用%config InlineBackend.figure_format = 'retina'来渲染更高分辨率的图像。
%matplotlib inline
%config InlineBackend.figure_format = 'retina'
import matplotlib.pyplot as plt
import matplotlib
import seaborn as sns
import numpy as np
import pandas as pd
Seaborn其实是在matplotlib的基础上进行了更高级的API封装,从而使得作图更加容易,在大多数情况下使用seaborn就能做出很具有吸引力的图,而使用matplotlib就能制作具有更多特色的图。应该把Seaborn视为matplotlib的补充,而不是替代物。
Matplotlib 是 Python 的绘图库。 它可与 NumPy 一起使用,提供了一种有效的 MatLab 开源替代方案。 它也可以和图形工具包一起使用,如 PyQt 和 wxPython。
matplotlib中的所有内容都按层次结构进行组织。 在层次结构的顶部是matplotlib“状态机环境”,它由matplotlib.pyplot模块提供
。 在此级别,简单函数用于将绘图元素(线条,图像,文本等)添加到当前图形中的当前轴。
层次结构中的下一级是面向对象的接口的第一级,其中pyplot仅用于少数函数,例如图形创建,并且用户显式创建并跟踪图形和轴对象
。 在此级别,用户使用pyplot来创建图形,并且通过这些图形,可以创建一个或多个轴对象。 然后,这些轴对象用于大多数绘图操作。
对于更多的控制 - 这对于在GUI应用程序中嵌入matplotlib图这一点至关重要 - 可以完全删除pyplot级别,留下纯粹的面向对象的方法。
Matplotlib 默认情况不支持中文,我们可以使用以下简单的方法来解决:
首先下载字体(注意系统):https://www.fontpalace.com/font-details/SimHei/
SimHei.ttf 文件放在当前执行的代码文件中:
import matplotlib as mpl
# fname 为 你下载的字体库路径,注意 SimHei.ttf 字体的路径
font1 = mpl.font_manager.FontProperties(fname="D:\py_files\SimHei.ttf")
x = np.arange(1,11)
y = 2 * x + 5
plt.title("标题 - 测试", fontproperties=font1)
# fontproperties 设置中文显示,fontsize 设置字体大小
plt.xlabel("x 轴", fontproperties=font1)
plt.ylabel("y 轴", fontproperties=font1)
plt.plot(x,y)
[]
此外,我们还可以使用系统的字体:
#打印出你的 font_manager 的 ttflist 中所有注册的名字
sorted([f.name for f in matplotlib.font_manager.fontManager.ttflist])
['Agency FB',
'Agency FB',
'STIXSizeOneSym',
'STIXSizeOneSym',
'STIXSizeThreeSym',
'cmtt10']
找一个看中文字体例如:SimHei(黑体),然后添加以下代码即可:
plt.rcParams['font.family']=['SimHei']
x = np.arange(1,11)
y = 2 * x + 5
plt.title("标题 - 测试", fontproperties=font1,fontsize=18)
# fontproperties 设置中文显示,fontsize 设置字体大小
plt.xlabel("x 轴", fontproperties=font1,fontsize=15)
plt.ylabel("y 轴", fontproperties=font1)
plt.plot(x,y)
作为线性图的替代,可以通过向 plot() 函数添加格式字符串来显示离散值。 可以使用以下格式化字符。
字符 | 描述 |
---|---|
‘-’ | 实线样式 |
‘–’ | 短横线样式 |
‘-.’ | 点划线样式 |
‘:’ | 虚线样式 |
‘.’ | 点标记 |
‘,’ | 像素标记 |
‘o’ | 圆标记 |
‘v’ | 倒三角标记 |
‘^’ | 正三角标记 |
‘<’ | 左三角标记 |
‘>’ | 右三角标记 |
‘1’ | 下箭头标记 |
‘2’ | 上箭头标记 |
‘3’ | 左箭头标记 |
‘4’ | 右箭头标记 |
‘s’ | 正方形标记 |
‘p’ | |
‘*’ | 星形标记 |
‘h’ | 六边形标记 1 |
‘H’ | 六边形标记 2 |
‘+’ | 加号标记 |
‘x’ | X 标记 |
‘D’ | 菱形标记 |
‘d’ | 窄菱形标记 |
‘|’ | 竖直线标记 |
‘_’ | 水平线标记 |
以下是颜色的缩写:
字符 | 颜色 |
---|---|
‘b’ | 蓝色 |
‘g’ | 绿色 |
‘r’ | 红色 |
‘c’ | 青色 |
‘m’ | 品红色 |
‘y’ | 黄色 |
‘k’ | 黑色 |
‘w’ | 白色 |
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,"ob")
plt.show()```
#### 2.4 处理显示为方框问题
```python
#绘制正弦波
x = np.arange(0, 3 * np.pi, 0.1)
y = np.sin(x)
plt.title("sine wave form")
# 使用 matplotlib 来绘制点
plt.plot(x, y)
# plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus']=False #用来正常显示负号
plt.show()
subplot() 函数允许你在同一图中绘制不同的东西。
# 计算正弦和余弦曲线上的点的 x 和 y 坐标
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,'-.')
plt.title('Sine')
# 将第二个 subplot 激活,并绘制第二个图像
plt.subplot(2, 1, 2)
plt.plot(x, y_cos,'1')
plt.title('Cosine')
# 展示图像
plt.show()
print(' ====分割线==== ')
plt.plot(x, y_sin,":")
plt.plot(x, y_cos,'v')
plt.title('Sine and Cosine')
plt.show()
====分割线====
注意,pyplot的方式中plt.subplot()参数和面向对象中的add_subplot()参数和含义都相同。
x = np.arange(1, 100)
fig = plt.figure()
ax1 = fig.add_subplot(221)
ax1.plot(x, x)
ax2 = fig.add_subplot(222)
ax2.plot(x, -x)
ax3 = fig.add_subplot(223)
ax3.plot(x, x ** 2)
ax4 = fig.add_subplot(224)
ax4.plot(x, np.log(x))
plt.show()
x = np.arange(0, 100)
plt.subplot(221)
plt.plot(x, x)
plt.subplot(222)
plt.plot(x, -x)
plt.subplot(223)
plt.plot(x, x ** 2)
plt.subplot(224)
plt.plot(x, np.log(x))
备注:subplot(224)中参数221等价subplot(2,2,4),前者简写适用于参数0~9
x = [5,8,10]
y = [12,16,6]
x2 = [6,8,11]
y2 = [6,20,7]
plt.bar(x, y, align = 'center')
plt.bar(x2, y2, color = 'g', align = 'center',alpha=0.6) #后画的图“覆盖”先画的图,alpha设置透明度
plt.title('Bar graph')
plt.ylabel('Y axis')
plt.xlabel('X axis')
#很明显,这样分组画图十分不便。
Text(0.5, 0, 'X axis')
numpy.histogram()
numpy.histogram() 函数是数据的频率分布的图形表示。
水平尺寸相等的矩形对应于类间隔,称为 bin,变量 height 对应于频率。
numpy.histogram()函数将输入数组和 bin 作为两个参数。 bin 数组中的连续元素用作每个 bin 的边界。
示例2.7-1:
a = np.array([22,87,5,43,56,73,23,55,54,11,20,51,5,79,31,27])
np.histogram(a,bins = [0,20,40,60,80,100])
hist,bins = np.histogram(a,bins = [0,20,40,60,80,100])
print (hist)
print (bins)
[3 5 5 2 1]
[ 0 20 40 60 80 100]
Matplotlib.pyplot.hist()
Matplotlib 可以将直方图的数字表示转换为图形。 pyplot 子模块的 plt() 函数将包含数据和 bin 数组的数组作为参数,并转换为直方图。
示例2.7-2:
a = np.array([22,87,5,43,56,73,55,54,11,20,51,5,79,31,27,88,99,97])
plt.hist(a, bins = [0,20,40,60,80,100])
plt.title("histogram")
plt.show()
# help(plt.figure().add_subplot) #多用help
plt.legend(loc='best',bbox_to_anchor=(0.1,0.2))
String | Number |
---|---|
upper right | 1 |
upper left | 2 |
lower left | 3 |
lower right | 4 |
right | 5 |
center left | 6 |
center right | 7 |
lower center | 8 |
upper center | 9 |
center | 10 |
所以loc这个参数可以设置大概的图例位置,如果这就可以满足要求,那么第二个参数不要也行。
第二个参数bbox_to_anchor被赋予的二元组中,num1用于控制legend的左右移动,值越大越向右边移动,num2用于控制legend的上下移动,值越大,越向上移动。用于微调图例的位置。
# 本cell仅供参考,未实际验证。
def pass_c():
if 2>1:
pass
else:
fig = plt.figure(facecolor='white')
ax1 = fig.add_subplot(211)
# 可用MarkerEdgeColor或mec设置标记边缘颜色;MarkerFaceColor或mfc设置标记填充颜色;
# MarkerSize设置标记大小 (这个点真心不好找,无意间看了一个无关的帖子瞅到了这个点)
ax1.plot(true_data, marker='o', color='r', mec='r', mfc='w',label=u'真实值') # r:红色 w:白色 g:绿色 b:蓝色 c:青绿色 m:洋红色 k:黑色
ax1.plot(predicted_data, '+-', MarkerSize=8, color='k', mec='k', mfc='w', label=u'预测值')
plt.setp(ax1.get_xticklabels(), visible=False) # 获得当前图像x轴,设置不可见
plt.ylabel(u'y1轴标签', fontproperties=font) # 设置图中汉字,可解决汉字乱码问题
plt.ylim(ymin=2) # 设置当前图像y轴的最小值,根据需要设置
ax1.legend(prop=font) # 设在当前图像标签 ,两个子图避免覆盖,此处需设置当前子图的属性,不设置的话上面的两个label显示不出来
ax2 = fig.add_subplot(212, sharex=ax1) # 共享x轴
ax2.bar(range(96), error_data, color='k')
plt.xlabel(u'时间段', fontproperties=font)
plt.ylabel(u'y2轴标签', fontproperties=font)
plt.subplots_adjust(hspace=0) # 设置两个子图的间距
plt.ylim(ymax=110) # 设置当前图像y轴的最大值
plt.ylim(ymin=-110) # 设置当前图像y轴的最小值
比如说需要在一张图上绘制两条曲线,分别是南方和北方的气温变化,分别用不同的颜色加以区分。在seaborn中用hue参数控制分组绘图。
其实就是在一张纸上划分不同的区域,比如2*2的子区域,在不同的子区域上绘制不同的图形,在matplotlib中就是 add_subplot(2,2,1),在seaborn中用col参数控制,col的全称是columns,不是color,如果辅助col_wrap参数会更好些。后来发现,col可以控制columns的子图,那么row可以控制rows的子图排列。
如果需要分面绘图,应该使用seaborn的FacetGrid对象,seaborn的一般的绘图函数是没有分面这个参数的。
分组绘图的时候,会对分组变量先要用统计函数,然后绘图,比如先计算变量的均值,然后绘制该均值的直方图。统计绘图参数是 estimator,很多情况下默认是numpy.mean。在R语言ggplot2中就大量使用了这种方法。如果不用统计绘图,就需要先用pandas进行groupby分组汇总,然后用seaborn绘图,多此一举了。
在seaborn中图形大概分这么几类,因子变量绘图,数值变量绘图,两变量关系绘图,时间序列图,热力图,分面绘图等。
因子变量绘图
回归图
回归图只要探讨两连续数值变量的变化趋势情况,绘制x-y的散点图和回归曲线。
分布图
包括单变量核密度曲线,直方图,双变量多变量的联合直方图,和密度图
热力图
聚类图
时间序列图
分面绘图
1.分面绘图FacetGrid
import seaborn as sns
seaborn支持5种主题:
1.darkgrid(灰色网格)
2.whitegrid(白色网格)
3.dark(黑色)
4.white(白色)
5.ticks(十字叉)
# 设置主题
sns.set_style("darkgrid")
调色板参考链接
颜色主题有6种不同的风格: deep, muted, pastel, bright, dark和colorblind。
当你有6种以上颜色需要区分的时候,最为常见的方式是采用hls颜色空间,这是一个RGB值的简单转换:
sns.palplot(sns.color_palette("hls", 10))#palplot是创建调色板 color_palette(颜色空间,设置几种颜色块)
# sns.color_palette("hls", 10)
color_palette()能传入任何Matplotlib所支持的颜色
color_palette()不写参数则默认颜色
set_palette()设置所有图的颜色
(绘图时使用参数palette设置颜色)
tips = sns.load_dataset("tips") #导入sns内置数据集(在线连接)
tips.describe(include='all')
# tips.head(5)
total_bill | tip | sex | smoker | day | time | size | |
---|---|---|---|---|---|---|---|
count | 244.000000 | 244.000000 | 244 | 244 | 244 | 244 | 244.000000 |
unique | NaN | NaN | 2 | 2 | 4 | 2 | NaN |
top | NaN | NaN | Male | No | Sat | Dinner | NaN |
freq | NaN | NaN | 157 | 151 | 87 | 176 | NaN |
mean | 19.785943 | 2.998279 | NaN | NaN | NaN | NaN | 2.569672 |
std | 8.902412 | 1.383638 | NaN | NaN | NaN | NaN | 0.951100 |
min | 3.070000 | 1.000000 | NaN | NaN | NaN | NaN | 1.000000 |
25% | 13.347500 | 2.000000 | NaN | NaN | NaN | NaN | 2.000000 |
50% | 17.795000 | 2.900000 | NaN | NaN | NaN | NaN | 2.000000 |
75% | 24.127500 | 3.562500 | NaN | NaN | NaN | NaN | 3.000000 |
max | 50.810000 | 10.000000 | NaN | NaN | NaN | NaN | 6.000000 |
# 绘制箱线图
ax = sns.boxplot(x=tips["total_bill"])
# 竖着放的箱线图,也就是将x换成y
# ax = sns.boxplot(y=tips["total_bill"])
# 分组绘制箱线图,分组因子是day,在x轴不同位置绘制(data为DataFrame格式,x、y对应赋值“字段”)
ax = sns.boxplot(x="day", y="total_bill", data=tips)
# 分组箱线图,分子因子是smoker,不同的因子用不同颜色区分
# 相当于分组之后又分组
ax = sns.boxplot(x="day", y="total_bill", hue="smoker",
data=tips,palette=sns.color_palette("hls", 2))
# 改变线宽,linewidth参数
ax = sns.boxplot(x="day", y="total_bill", hue="time",
data=tips,linewidth=5.2, palette='Set2')
# 改变x轴顺序,order参数
ax = sns.boxplot(x="time", y="tip", data=tips,
order=["Dinner", "Lunch"],palette='Set3')
# 对dataframe的每个变量都绘制一个箱线图,水平放置 orient='h'为水平的、默认为垂直的
iris = sns.load_dataset("iris")
ax = sns.boxplot(data=iris.iloc[:,[3,2,1,0]],orient="h", palette="Set3")
# 注:每个数值型“字段”都自动分组,支持索引排序,但类似iris.iloc[:,[3,3,2,2]]的索引会出图错误。
iris.head(5)
sepal_length | sepal_width | petal_length | petal_width | species | |
---|---|---|---|---|---|
0 | 5.1 | 3.5 | 1.4 | 0.2 | setosa |
1 | 4.9 | 3.0 | 1.4 | 0.2 | setosa |
2 | 4.7 | 3.2 | 1.3 | 0.2 | setosa |
3 | 4.6 | 3.1 | 1.5 | 0.2 | setosa |
4 | 5.0 | 3.6 | 1.4 | 0.2 | setosa |
# 箱线图+有分布趋势的散点图
# 图形组合也就是两条绘图语句一起运行就可以了,相当于图形覆盖了
ax = sns.boxplot(x="day", y="total_bill", data=tips)
ax = sns.swarmplot(x="day", y="total_bill", data=tips, color="0.2",alpha=0.6)
小提琴图其实是箱线图与核密度图的结合,箱线图展示了分位数的位置,小提琴图则展示了任意位置的密度,通过小提琴图可以知道哪些位置的密度较高。在图中,白点是中位数,黑色盒型的范围是下四分位点到上四分位点,细黑线表示须。外部形状即为核密度估计(在概率论中用来估计未知的密度函数,属于非参数检验方法之一)。
# 绘制小提琴图(x轴指定数据)
ax = sns.violinplot(x=tips["total_bill"],orient='v')#注:未指定y轴时,x轴默认横向,用orient='v'改为垂直
tips["total_bill"].head(5)
C:\ProgramData\Anaconda3\lib\site-packages\scipy\stats\stats.py:1713: FutureWarning: Using a non-tuple sequence for multidimensional indexing is deprecated; use `arr[tuple(seq)]` instead of `arr[seq]`. In the future this will be interpreted as an array index, `arr[np.array(seq)]`, which will result either in an error or a different result.
return np.add.reduce(sorted[indexer] * weights, axis=axis) / sumval
0 16.99
1 10.34
2 21.01
3 23.68
4 24.59
Name: total_bill, dtype: float64
# 分组的小提琴图,同上面的箱线图一样通过X轴分组
ax = sns.violinplot(x="day", y="total_bill", data=tips)
# 通过hue分组的小提琴图,相当于分组之后又分组
ax = sns.violinplot(x="day", y="total_bill", hue="smoker",
data=tips, palette=sns.color_palette("hls", 2))
# 分组组合的小提琴图,其实就是hue分组后,各取一半组成一个小提琴图 :split=True
ax = sns.violinplot(x="day", y="total_bill", hue="smoker",
data=tips, palette=sns.color_palette("hls", 2),
split=True)
# ax=sns.swarmplot(x='day',y='total_bill',data=tips,hue='smoker',alpha=0.5) # 当然,可以叠加散点图
# 调整x轴顺序,同样通过order参数
ax = sns.violinplot(x="day", y="total_bill", hue="smoker",
data=tips, palette=sns.color_palette("hls", 2),split=True,
order=['Fri','Sat','Sun','Thur'])
需要注意的是,seaborn中有两个散点图,一个是普通的散点图,另一个是可以看出分布密度的散点图。下面把它们花在一起就明白了。
tips["total_bill"].head(10)
0 16.99
1 10.34
2 21.01
3 23.68
4 24.59
5 25.29
6 8.77
7 26.88
8 15.04
9 14.78
Name: total_bill, dtype: float64
# 普通的散点图
ax1 = sns.stripplot(x=tips["total_bill"])
# 带分布密度的散点图
ax2 = sns.swarmplot(x=tips["total_bill"])
# 分组的散点图 #添加抖动,jitter可以是0.1,0.2...这样的小数,表示抖动的程度大小
ax = sns.stripplot(x="day", y="total_bill", data=tips,jitter=0.3)
# 是不是想横着放呢,很简单的,x-y顺序换一下就好了
# 重点来了,分组绘制,而且是分组后分开绘制,在柱状图中,跟分组柱状图类似的。
# 通过 hue, split 参数控制
# 1.分组
ax = sns.stripplot(x="sex", y="total_bill", hue="day",
data=tips, jitter=True)
# 2.分开绘制
ax = sns.stripplot(x="sex", y="total_bill", hue="day",
data=tips, jitter=True,dodge=True) #dodge是`split`被重命名了。
# help(sns.stripplot().legend)
swarmplt的参数和用法和stripplot的用法是一样的,只是表现形式不一样而已。
基于 help(sns.pointplot)
点图代表散点图位置的数值变量的中心趋势估计,并使用误差线提供关于该估计的不确定性的一些指示。点图可能比条形图更有用于聚焦一个或多个分类变量的不同级别之间的比较。他们尤其善于表现交互作用:一个分类变量的层次之间的关系如何在第二个分类变量的层次之间变化。连接来自相同色调等级的每个点的线允许交互作用通过斜率的差异进行判断,这比对几组点或条的高度比较容易。具体用法如下:
seaborn.pointplot(x=None, y=None, hue=None, data=None, order=None, hue_order=None, estimator=(function mean), ci=95, n_boot=1000, units=None, markers=‘o’, linestyles=’-’, dodge=False, join=True, scale=1, orient=None, color=None, palette=None, errwidth=None, capsize=None, ax=None, **kwargs)
误差棒是以被测量的算术平均值为中点,在表示测量值大小的方向上画出的一个线段,线段长度的一半等于(标准或扩展)不确定度。它表示被测量以某一概率(68%或95%)落在棒上。
tips.head(5)
total_bill | tip | sex | smoker | day | time | size | |
---|---|---|---|---|---|---|---|
0 | 16.99 | 1.01 | Female | No | Sun | Dinner | 2 |
1 | 10.34 | 1.66 | Male | No | Sun | Dinner | 3 |
2 | 21.01 | 3.50 | Male | No | Sun | Dinner | 3 |
3 | 23.68 | 3.31 | Male | No | Sun | Dinner | 2 |
4 | 24.59 | 3.61 | Female | No | Sun | Dinner | 4 |
sns.pointplot(x="time",y="size",data=tips,ci=68)
#点为这组数据的平均值点,竖线则为误差棒,默认两个均值点会相连接,若不想显示,可以通过join参数实现
sns.pointplot(x="time",y="size",data=tips,join=False)
# 同样的,hue分组,dodge分离
# markers控制均值点的样式,linestyles控制相同色调的点之间的连线
sns.pointplot(x="time",y="size",data=tips,hue='smoker',dodge=True,
markers=["*","x"],linestyles=["-.","--"]) # 注意哪些用split,哪些用dodge
plt.legend(loc='lower left',bbox_to_anchor=(0.01,0.2)) #设置图例位置,一般用loc='best',第二参数可省略
ax = sns.barplot(x="day", y="total_bill", data=tips,ci=95)
# 不显示条形图上面的置信度线,可以令置信区间参数ci=0
直方图的统计函数,默认绘制的是变量的均值 estimator=np.mean
# 要绘制变量中位数的条形图,由estimator指定统计函数
ax = sns.barplot(x="day", y="tip", data=tips,
estimator=np.median, ci=0)
# 其他分组颜色等和前文图类似
countplot 故名思意,是“计数图”的意思,可将它认为一种应用到分类变量的直方图,也可认为它是用以比较类别间计数差,调用 count 函数的 barplot;
countplot 参数和 barplot 基本差不多,可以对比着记忆,有一点不同的是 countplot 中不能同时输入 x 和 y ,且 countplot 没有误差棒。
titanic = sns.load_dataset("titanic")
titanic.head(10)
survived | pclass | sex | age | sibsp | parch | fare | embarked | class | who | adult_male | deck | embark_town | alive | alone | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 0 | 3 | male | 22.0 | 1 | 0 | 7.2500 | S | Third | man | True | NaN | Southampton | no | False |
1 | 1 | 1 | female | 38.0 | 1 | 0 | 71.2833 | C | First | woman | False | C | Cherbourg | yes | False |
2 | 1 | 3 | female | 26.0 | 0 | 0 | 7.9250 | S | Third | woman | False | NaN | Southampton | yes | True |
3 | 1 | 1 | female | 35.0 | 1 | 0 | 53.1000 | S | First | woman | False | C | Southampton | yes | False |
4 | 0 | 3 | male | 35.0 | 0 | 0 | 8.0500 | S | Third | man | True | NaN | Southampton | no | True |
5 | 0 | 3 | male | NaN | 0 | 0 | 8.4583 | Q | Third | man | True | NaN | Queenstown | no | True |
6 | 0 | 1 | male | 54.0 | 0 | 0 | 51.8625 | S | First | man | True | E | Southampton | no | True |
7 | 0 | 3 | male | 2.0 | 3 | 1 | 21.0750 | S | Third | child | False | NaN | Southampton | no | False |
8 | 1 | 3 | female | 27.0 | 0 | 2 | 11.1333 | S | Third | woman | False | NaN | Southampton | yes | False |
9 | 1 | 2 | female | 14.0 | 1 | 0 | 30.0708 | C | Second | child | False | NaN | Cherbourg | yes | False |
ax = sns.countplot(x="class", data=titanic)
原“factorplot”函数已重命名为“catplot”。原始名称将在未来的版本中删除。请更新您的代码。
catplot(x=None, y=None, hue=None, data=None, row=None, col=None, col_wrap=None, estimator=
, ci=95, n_boot=1000, units=None, order=None, hue_order=None, row_order=None, col_order=None, kind=‘strip’, height=5, aspect=1, orient=None, color=None, palette=None, legend=True, legend_out=True, sharex=True, sharey=True, margin_titles=False, facet_kws=None, **kwargs)
参数kind:point默认,bar柱形图,count频次,box箱体,violin提琴,strip散点,swarm分散点
# help(sns.catplot)
titanic.head(10)
# titanic.describe(include='all')
survived | pclass | sex | age | sibsp | parch | fare | embarked | class | who | adult_male | deck | embark_town | alive | alone | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 0 | 3 | male | 22.0 | 1 | 0 | 7.2500 | S | Third | man | True | NaN | Southampton | no | False |
1 | 1 | 1 | female | 38.0 | 1 | 0 | 71.2833 | C | First | woman | False | C | Cherbourg | yes | False |
2 | 1 | 3 | female | 26.0 | 0 | 0 | 7.9250 | S | Third | woman | False | NaN | Southampton | yes | True |
3 | 1 | 1 | female | 35.0 | 1 | 0 | 53.1000 | S | First | woman | False | C | Southampton | yes | False |
4 | 0 | 3 | male | 35.0 | 0 | 0 | 8.0500 | S | Third | man | True | NaN | Southampton | no | True |
5 | 0 | 3 | male | NaN | 0 | 0 | 8.4583 | Q | Third | man | True | NaN | Queenstown | no | True |
6 | 0 | 1 | male | 54.0 | 0 | 0 | 51.8625 | S | First | man | True | E | Southampton | no | True |
7 | 0 | 3 | male | 2.0 | 3 | 1 | 21.0750 | S | Third | child | False | NaN | Southampton | no | False |
8 | 1 | 3 | female | 27.0 | 0 | 2 | 11.1333 | S | Third | woman | False | NaN | Southampton | yes | False |
9 | 1 | 2 | female | 14.0 | 1 | 0 | 30.0708 | C | Second | child | False | NaN | Cherbourg | yes | False |
# 不同的deck(因子)绘制不同的alive(数值),col为分子图绘制,col_wrap每行画4个子图
g = sns.catplot(x="alive", col="deck", col_wrap=4,
data=titanic[titanic.deck.notnull()],
kind="count", height=2.5, aspect=.8)
# help(titanic.deck.notnull)
type(titanic.age.notnull)
method
regplot:Plot data and a linear regression model fit(与线性回归模型拟合)。
lmplot: Plot data and regression model fits across a FacetGrid(回归模型适用于整个FacetGrid)
tips.head(5)
total_bill | tip | sex | smoker | day | time | size | |
---|---|---|---|---|---|---|---|
0 | 16.99 | 1.01 | Female | No | Sun | Dinner | 2 |
1 | 10.34 | 1.66 | Male | No | Sun | Dinner | 3 |
2 | 21.01 | 3.50 | Male | No | Sun | Dinner | 3 |
3 | 23.68 | 3.31 | Male | No | Sun | Dinner | 2 |
4 | 24.59 | 3.61 | Female | No | Sun | Dinner | 4 |
# 简单绘制regplot
sns.regplot(x="tip", y="total_bill", data=tips)
# 简单使用lmplot()
sns.lmplot(y="total_bill", x="tip", data=tips,markers='x')
# x_jitter 表示沿轴随机分布,相对避免重叠
sns.lmplot(x="size", y="tip", data=tips, x_jitter=.05)
sns.lmplot(x="size", y="tip", data=tips, x_estimator=np.mean)
# help(sns.lmplot)
anscombe = sns.load_dataset("anscombe")
anscombe[::-5]
dataset | x | y | |
---|---|---|---|
43 | IV | 8.0 | 6.89 |
38 | IV | 8.0 | 7.04 |
33 | IV | 8.0 | 6.58 |
28 | III | 6.0 | 6.08 |
23 | III | 8.0 | 6.77 |
18 | II | 4.0 | 3.10 |
13 | II | 13.0 | 8.74 |
8 | I | 12.0 | 10.84 |
3 | I | 9.0 | 8.81 |
# 原来数据还可以这样查询 anscombe.query("dataset == 'I'")
sns.lmplot(x="x", y="y", data=anscombe.query("dataset == 'I'"), ci=None, scatter_kws={"s": 50}) #scatter_kw控制散点大小
sns.lmplot(x="x", y="y", data=anscombe.query("dataset == 'II'"),ci=None, scatter_kws={"s":50})
sns.lmplot(x="x", y="y", data=anscombe.query("dataset == 'II'"),order=2, ci=None, scatter_kws={"s": 50})
sns.lmplot(x="x", y="y", data=anscombe.query("dataset == 'III'"),ci=None, scatter_kws={"s": 170})
# robust=True 使用 robust回归
sns.lmplot(x="x", y="y", data=anscombe.query("dataset == 'III'"),robust=True, ci=None, scatter_kws={"s": 180})
tips["big_tip"] = (tips.tip / tips.total_bill) > .15
# sns.lmplot(x="total_bill", y="big_tip", data=tips, y_jitter=.03)
# 使用逻辑回归
sns.lmplot(x="total_bill", y="big_tip", data=tips,logistic=True, y_jitter=.03)
# 非参数回归
sns.lmplot(x="total_bill", y="tip", data=tips,lowess=True)
# 绘制残差分布
sns.residplot(x="x", y="y", data=anscombe.query("dataset == 'I'"),scatter_kws={"s": 80},color='gray');
# 增加分类
# sns.lmplot(x="total_bill", y="tip", hue="smoker", data=tips)
# 横向增加时间变量
# sns.lmplot(x="total_bill", y="tip", hue="smoker", col="time", data=tips)
# 纵向增加性别变量
sns.lmplot(x="total_bill", y="tip", hue="smoker",col="time", row="sex", data=tips,height=5)
# sns.lmplot(x="total_bill", y="tip", hue="smoker",row="time", col="sex", data=tips)
# 分两行显示 col_wrap=2
# sns.lmplot(x="total_bill", y="tip", col="day",col_wrap=2,data=tips)
第一种是进行多项式拟合,数学上可以证明,任意函数都可以表示为多项式形式。具体示例如下。
x = [10,20,30,40,50,60,70,80]
x = np.array(x)
print('x is :\n',x)
num = [174,236,305,334,349,351,342,323]
y = np.array(num)
print('y is :\n',y)
#用3次多项式拟合
f1 = np.polyfit(x, y, 3)
print('f1 is :\n',f1)
p1 = np.poly1d(f1)
print('p1 is :\n',p1)
#也可使用yvals=np.polyval(f1, x)
yvals = p1(x) #拟合y值
print('yvals is :\n',yvals)
plot1 = plt.plot(x, y, 's',label='original values')
plot2 = plt.plot(x, yvals, 'r',label='polyfit values')
plt.xlabel('x')
plt.ylabel('y')
plt.legend(loc=4) #指定legend的位置右下角
plt.title('polyfitting')
x is :
[10 20 30 40 50 60 70 80]
y is :
[174 236 305 334 349 351 342 323]
f1 is :
[ 3.68686869e-04 -1.28701299e-01 1.10570707e+01 7.26428571e+01]
p1 is :
3 2
0.0003687 x - 0.1287 x + 11.06 x + 72.64
yvals is :
[170.71212121 245.25324675 298.47835498 332.5995671 349.82900433
352.37878788 342.46103896 322.28787879]
Text(0.5, 1.0, 'polyfitting')
第一种方案是给出具体的函数形式(可以是任意的,只要你能写的出来 下面的func就是),用最小二乘的方式去逼近和拟合,求出函数的各项系数,如下。
##使用curve_fit
from scipy.optimize import curve_fit
#自定义函数 e指数形式
def func(x, a, b,c):
return a*np.sqrt(x)*(b*np.square(x)+c)
#定义x、y散点坐标
x = [20,30,40,50,60,70]
x = np.array(x)
num = [453,482,503,508,498,479]
y = np.array(num)
#非线性最小二乘法拟合
popt, pcov = curve_fit(func, x, y)
#获取popt里面是拟合系数
print(popt)
a = popt[0]
b = popt[1]
c = popt[2]
yvals = func(x,a,b,c) #拟合y值
print('popt:', popt)
print('系数a:', a)
print('系数b:', b)
print('系数c:', c)
print('系数pcov:', pcov)
print('系数yvals:', yvals)
#绘图
plot1 = plt.plot(x, y, 's',label='original values')
plot2 = plt.plot(x, yvals, 'r',label='polyfit values')
plt.xlabel('x')
plt.ylabel('y')
plt.legend(loc=4) #指定legend的位置右下角
plt.title('curve_fit')
plt.show()
[-1.96401671e-01 4.20401375e-02 -4.85953552e+02]
popt: [-1.96401671e-01 4.20401375e-02 -4.85953552e+02]
系数a: -0.19640167051933263
系数b: 0.042040137450105416
系数c: -485.95355159953976
系数pcov: [[-8.40140633e+10 -1.79833643e+10 2.07874670e+14]
[-1.79833643e+10 -3.84937212e+09 4.44959544e+13]
[ 2.07874670e+14 4.44959544e+13 -5.14341015e+17]]
系数yvals: [412.05987012 482.05616268 520.0763058 528.91733087 509.04771734
460.0291367 ]
#encoding=utf-8
# import numpy as np
# import matplotlib.pyplot as plt
# from scipy.optimize import curve_fit
# import pandas as pd
import math
#自定义函数 e指数形式
def func(x, a,u, sig):
return a*(np.exp(-(x - u) ** 2 /(2* sig **2))/(math.sqrt(2*math.pi)*sig))*(431+(4750/x))
#定义x、y散点坐标
x = [40,45,50,55,60,65,70,75,80,85,90,95,100,105,110,115,120,125,130,135]
x=np.array(x)
# x = np.array(range(20))
print('x is :\n',x)
num = [536,529,522,516,511,506,502,498,494,490,487,484,481,478,475,472,470,467,465,463]
y = np.array(num)
print('y is :\n',y)
popt, pcov = curve_fit(func, x, y,p0=[3.1,4.2,3.3])
#获取popt里面是拟合系数
a = popt[0]
u = popt[1]
sig = popt[2]
yvals = func(x,a,u,sig) #拟合y值
print(u'系数a:', a)
print(u'系数u:', u)
print(u'系数sig:', sig)
#绘图
plot1 = plt.plot(x, y, 's',label='original values')
plot2 = plt.plot(x, yvals, 'r',label='polyfit values')
plt.xlabel('x')
plt.ylabel('y')
plt.legend(loc='best')
plt.title('curve_fit')
plt.show()
x is :
[ 40 45 50 55 60 65 70 75 80 85 90 95 100 105 110 115 120 125
130 135]
y is :
[536 529 522 516 511 506 502 498 494 490 487 484 481 478 475 472 470 467
465 463]
系数a: 3.1
系数u: 4.2
系数sig: 3.3
C:\ProgramData\Anaconda3\lib\site-packages\scipy\optimize\minpack.py:794: OptimizeWarning: Covariance of the parameters could not be estimated
category=OptimizeWarning)
默认:直方图hist=True,核密度曲线rug=True
sns.set(rc={"figure.figsize": (8, 4)}); np.random.seed(0)
x = np.random.randn(100)
# 绘制数值变量的密度分布图
# 默认既绘制核密度曲线,也绘制直方图
# ax = sns.distplot(x)
# 只绘制核密度曲线,不绘制直返图
# ax = sns.distplot(x, rug=True, hist=False)
# 横着放
ax = sns.distplot(x, vertical=True)
# import numpy as np; np.random.seed(10)
# import seaborn as sns; sns.set(color_codes=True)
mean, cov = [0, 2], [(1, .5), (.5, 1)]
x, y = np.random.multivariate_normal(mean, cov, size=50).T #随机数生成
# 绘制核密度图
ax = sns.kdeplot(x)
# shade参数决定是否填充曲线下面积
# ax = sns.kdeplot(x, shade=True, color="r")
# 双变量密度图,相当于等高线图了
# shade 参数改用颜色深浅表示密度的大小,不过不用(就真的是等高线了)
ax = sns.kdeplot(x, y, shade=True)
# 分组绘制双变量的核密度图
# 相当于绘制两个核密度图,通过图可以看到密度中心
# 类似于挖掘算法中聚类中心绘图
iris = sns.load_dataset("iris")
setosa = iris.loc[iris.species == "setosa"] # 组1
virginica = iris.loc[iris.species == "virginica"] # 组2
ax = sns.kdeplot(setosa.sepal_width, setosa.sepal_length,
cmap="Reds", shade=True, shade_lowest=False)
ax = sns.kdeplot(virginica.sepal_width, virginica.sepal_length,
cmap="Blues", shade=True, shade_lowest=False)
np.random.seed(0)
cmap = sns.diverging_palette(220, 10, as_cmap=True) # 设置配色
uniform_data = np.random.rand(5, 8)
ax = sns.heatmap(uniform_data,cmap=cmap,annot=True) # annot:十分显示数值
# 改变颜色映射的值范围 vmin=0.2, vmax=0.6
ax = sns.heatmap(uniform_data,cmap=cmap,annot=True,vmin=0.5, vmax=0.6)
# Plot a dataframe with meaningful row and column labels:
flights = sns.load_dataset("flights")
flights = flights.pivot("month", "year", "passengers") # pivot 将 对应字段转化为 x-y-z结构(行-列-值)
# 绘制x-y-z的热力图,比如 年-月-销量 的热力图
cmap = sns.diverging_palette(220, 5, as_cmap=True) # 设置配色
ax = sns.heatmap(flights,cmap=cmap,annot=False,fmt="d") # fmt="d":添加注释时使用的字符串格式化代码
# xticklabels,yticklabels用来指定标签名称
np.random.seed(1)
data = pd.DataFrame(np.random.randn(8, 4))
data.columns=['a','b','c','d']
ax = sns.heatmap(data, xticklabels=['c','c','k'], yticklabels=['d','asd','dadw'],cmap=cmap,annot=True)
热力图可用户缺失值可视化,但数据量大时想要更直观,推荐一个**缺失值可视化包missingno**,这个包功能很简单,只有几个方法,使用起来也特别方便,不过它只能和pandas联合起来使用。
joint,顾名思义,就是联合呀。
Draw a plot of two variables with bivariate and univariate graphs.
(用双变量图和单变量图绘制一个由两个变量组成的图。)
kind参数可以使用不同的图形反应两变量的关系,比如点图,线图,核密度图。kind : { “scatter” | “reg” | “resid”(残差) | “kde” (等高线/核密度)| “hex” (六边形密度图)}, optional Kind of plot to draw.
space=0 "附图"间隔;height=5 正方形图边长, ratio=2 轴高比
# 默认绘制双变量的散点图,计算两个变量的直方图,计算两个变量的相关系数和置信度
# import numpy as np, pandas as pd; np.random.seed(0)
# import seaborn as sns; sns.set(style="white", color_codes=True)
tips = sns.load_dataset("tips")
g = sns.jointplot(x="total_bill", y="tip", data=tips)
# 使用六角形代替点图图
g = sns.jointplot("total_bill", "tip", data=tips, kind="hex")
# 绘制核密度图
iris = sns.load_dataset("iris")
g = sns.jointplot("sepal_width", "petal_length", data=iris,
kind="kde", space=0, color="g")
# 控制图形的大小和颜色
g = sns.jointplot("total_bill", "tip", data=tips,
height=5, ratio=5, color="g")
# help(sns.jointplot)
Plot pairwise relationships in a dataset.(在数据集中绘制成对关系。)
# help(sns.pairplot)
iris.head(5)
sepal_length | sepal_width | petal_length | petal_width | species | |
---|---|---|---|---|---|
0 | 5.1 | 3.5 | 1.4 | 0.2 | setosa |
1 | 4.9 | 3.0 | 1.4 | 0.2 | setosa |
2 | 4.7 | 3.2 | 1.3 | 0.2 | setosa |
3 | 4.6 | 3.1 | 1.5 | 0.2 | setosa |
4 | 5.0 | 3.6 | 1.4 | 0.2 | setosa |
# import seaborn as sns; sns.set(style="ticks", color_codes=True)
# iris = sns.load_dataset("iris")
g = sns.pairplot(iris)
help(sns.pairplot)
Help on function pairplot in module seaborn.axisgrid:
pairplot(data, hue=None, hue_order=None, palette=None, vars=None, x_vars=None, y_vars=None, kind='scatter', diag_kind='auto', markers=None, height=2.5, aspect=1, dropna=True, plot_kws=None, diag_kws=None, grid_kws=None, size=None)
Plot pairwise relationships in a dataset.
By default, this function will create a grid of Axes such that each
variable in ``data`` will by shared in the y-axis across a single row and
in the x-axis across a single column. The diagonal Axes are treated
differently, drawing a plot to show the univariate distribution of the data
for the variable in that column.
It is also possible to show a subset of variables or plot different
variables on the rows and columns.
This is a high-level interface for :class:`PairGrid` that is intended to
make it easy to draw a few common styles. You should use :class:`PairGrid`
directly if you need more flexibility.
Parameters
----------
data : DataFrame
Tidy (long-form) dataframe where each column is a variable and
each row is an observation.
hue : string (variable name), optional
Variable in ``data`` to map plot aspects to different colors.
hue_order : list of strings
Order for the levels of the hue variable in the palette
palette : dict or seaborn color palette
Set of colors for mapping the ``hue`` variable. If a dict, keys
should be values in the ``hue`` variable.
vars : list of variable names, optional
Variables within ``data`` to use, otherwise use every column with
a numeric datatype.
{x, y}_vars : lists of variable names, optional
Variables within ``data`` to use separately for the rows and
columns of the figure; i.e. to make a non-square plot.
kind : {'scatter', 'reg'}, optional
Kind of plot for the non-identity relationships.
diag_kind : {'auto', 'hist', 'kde'}, optional
Kind of plot for the diagonal subplots. The default depends on whether
``"hue"`` is used or not.
markers : single matplotlib marker code or list, optional
Either the marker to use for all datapoints or a list of markers with
a length the same as the number of levels in the hue variable so that
differently colored points will also have different scatterplot
markers.
height : scalar, optional
Height (in inches) of each facet.
aspect : scalar, optional
Aspect * height gives the width (in inches) of each facet.
dropna : boolean, optional
Drop missing values from the data before plotting.
{plot, diag, grid}_kws : dicts, optional
Dictionaries of keyword arguments.
Returns
-------
grid : PairGrid
Returns the underlying ``PairGrid`` instance for further tweaking.
See Also
--------
PairGrid : Subplot grid for more flexible plotting of pairwise
relationships.
Examples
--------
Draw scatterplots for joint relationships and histograms for univariate
distributions:
.. plot::
:context: close-figs
>>> import seaborn as sns; sns.set(style="ticks", color_codes=True)
>>> iris = sns.load_dataset("iris")
>>> g = sns.pairplot(iris)
Show different levels of a categorical variable by the color of plot
elements:
.. plot::
:context: close-figs
>>> g = sns.pairplot(iris, hue="species")
Use a different color palette:
.. plot::
:context: close-figs
>>> g = sns.pairplot(iris, hue="species", palette="husl")
Use different markers for each level of the hue variable:
.. plot::
:context: close-figs
>>> g = sns.pairplot(iris, hue="species", markers=["o", "s", "D"])
Plot a subset of variables:
.. plot::
:context: close-figs
>>> g = sns.pairplot(iris, vars=["sepal_width", "sepal_length"])
Draw larger plots:
.. plot::
:context: close-figs
>>> g = sns.pairplot(iris, height=3,
... vars=["sepal_width", "sepal_length"])
Plot different variables in the rows and columns:
.. plot::
:context: close-figs
>>> g = sns.pairplot(iris,
... x_vars=["sepal_width", "sepal_length"],
... y_vars=["petal_width", "petal_length"])
Use kernel density estimates for univariate plots:
.. plot::
:context: close-figs
>>> g = sns.pairplot(iris, diag_kind="kde")
Fit linear regression models to the scatter plots:
.. plot::
:context: close-figs
>>> g = sns.pairplot(iris, kind="reg")
Pass keyword arguments down to the underlying functions (it may be easier
to use :class:`PairGrid` directly):
.. plot::
:context: close-figs
>>> g = sns.pairplot(iris, diag_kind="kde", markers="+",
... plot_kws=dict(s=50, edgecolor="b", linewidth=1),
... diag_kws=dict(shade=True))
# 分组的变量关系图,似乎很厉害啊
g = sns.pairplot(iris, hue="species")
# hue 分组后,不同的组用不同的形状标记
# g = sns.pairplot(iris, hue="species", markers=["o", "s", "D"])
# 当然也可以只取dataframe中的一部分变量绘图
# g = sns.pairplot(iris, vars=["sepal_width", "sepal_length"])
# 对角线默认绘制直方图,当然也可以绘制核密度图
# g = sns.pairplot(iris, diag_kind="kde")
# 相应的,两变量关系图,也可以绘制线性回归图
# g = sns.pairplot(iris,kind='reg')
Plot a matrix dataset as a hierarchically-clustered heatmap.(将矩阵数据集绘制为分层聚类的热图。)
参数:
继承sns.heatmap;data不为空的2D array-like;默认:method=‘average’, metric=‘euclidean’, z_score=None,…
# help(sns.clustermap)
# type(iris.iloc[:,0:4])
ax=sns.clustermap(iris.iloc[0:4,0:4],cmap=cmap,figsize=(8,8))
连续时间可以用matplotlib.pyplot.plot(),但可视效果欠佳,将时间转为数字再注释也麻烦;
时间序列绘图常用lineplot(替换原tsplot)。
lineplot(x=None, y=None, hue=None, size=None, style=None, data=None, palette=None, hue_order=None, hue_norm=None, sizes=None, size_order=None, size_norm=None, dashes=True, markers=None, style_order=None, units=None, estimator=‘mean’, ci=95, n_boot=1000, sort=True, err_style=‘band’, err_kws=None, legend=‘brief’, ax=None, **kwargs)
iris.head(4)
sepal_length | sepal_width | petal_length | petal_width | species | |
---|---|---|---|---|---|
0 | 5.1 | 3.5 | 1.4 | 0.2 | setosa |
1 | 4.9 | 3.0 | 1.4 | 0.2 | setosa |
2 | 4.7 | 3.2 | 1.3 | 0.2 | setosa |
3 | 4.6 | 3.1 | 1.5 | 0.2 | setosa |
ax=sns.lineplot(x='sepal_length',y='sepal_width',data=iris,hue='species')
这里重点讲一下。如果时序中每天的数据都有还好说,如果没有,就需要采样了。
# import seaborn as sns
sale=pd.Series(np.random.random(10)*100).map(int)
tmperature=pd.Series(np.random.random(10)*10).map(int)
ax=plt.subplot(111)
sale.plot(ax=ax,color='b')
ax.set_xlabel('time')
ax.set_ylabel('sale')
# 重点来了,twinx 或者 twiny 函数
ax2 = ax.twinx()
tmperature.plot(ax=ax2,color='r')
ax2.set_ylabel('tmperature')
plt.title('double series figure')
Text(0.5, 1.0, 'double series figure')
fig = plt.figure()
ax=fig.add_subplot(111)
sub_data[years].plot('绘图')
file = r'E:\xxx.jpg' %lev3
savefig(file)
time.sleep(0.5) # 注意这里要暂停一下,不然会出问题的
plt.close() # 最后记得关闭句柄
这里借用panas.cut函数,因为是绘图看趋势,不需要精确得到每个分段的分割点。
# 先用pd.cut分段,并取出分段数值
# 通过 precision 控制小数的位数
data['cut_point']=pd.cut(data['age'],
bins=[0,3,5.9,8.9,11.9,14.8,17.8,20.8,23.8,26.7,29.7], # 分割点
labels=['0-3','3-5.9',......] # 区间命名
right=True, # 区间默认是坐开右闭
precision=1)
# 用sns画图,可以直接汇总每个分段的数量后绘图,而不需要groupby汇总
# 相当于回到前面,用barplot绘图
sns.barplot(x='cut_point',y='cnt', data=data, estimator=np.sum, ci=0)
plt.xlabel('这是横坐标名称')
plt.ylabel('这是纵坐标名称')
plt.title('这是图标标题')
# 和上面的一样,先分组取出分割点
# 用pd.cut分段,并取出分段数值,通过 precision 控制小数的位数
data['bins']=pd.cut(data['age'], bins=10,precision=1)
# 取出分割点,因为cut后得到的是 '(2.99, 5.97]' 这样的字符串
data['cut_point']=data['bins'].apply(lambda x: eval(x.replace(']',')'))[1])
# 下面重点来了,用FacetGrid进行子图绘制
g=sns.FacetGrid(data=data,col='platform',col_wrap=3,size=5) # 这里相当于groupby
g=g=g.map(sns.barplot,'cut_point','cnt',ci=0, estimator=np.sum)
# 很奇怪的是,如果写
# g=g.map(sns.barplot,x='cut_point',y='cnt',ci=0, estimator=np.sum)就报错。
def my_barplot(x,y,**kwargs):
"""
自定义函数的时候,没有显示传入dataframe,但是会自动获取,很神奇吧。(待验证)
x,y是dataframe的列名
"""
ax = plt.gca() # 【这个是重点,获取对应的ax子图句柄】
data['bins']=pd.cut(data['age'], bins=10,precision=1)
data['cutpoint']=data['bins'].apply(lambda x: eval(x.replace(']', ')'))[1])
sns.barplot(x='cutpoint', y='cnt',data=data, estimator=np.sum, ci=0, ax=ax)
g = sns.FacetGrid(data=data, col='platform',col_wrap=3,
size=5,sharex=False)
g = g.map(my_barplot,'age','cnt')