7天学会python_7天学会Python最佳可视化工具Seaborn(五):结构化展示多维数据

当探索具有中等数量(不多不少的意思……)维度的数据集时,一个很好的方式是基于不同的子数据集构建不同的实例,并将它们以网格的方式组织在一张图之中。这种技术有时被称为“lattice”或“trellis”(大概是格子图、网格图),这跟“small multiples”的概念类似(多张更小的子图)。它能帮助我们快速从复杂的数据中提取大量信息。matplotlib对于创建带有多个坐标轴(每个坐标轴体系意味着一张子图)的图形有着良好的支持,seaborn基于这些来直接地将图形的排布结构与数据集的结构联结起来。

要利用这些特性,我们的数据集应该保存在一个pandas DataFrame中,并且应该是Hadley Whickam口中的“tidy data”格式。简短来说,就是我们的dataframe对象中,每一行是一个观测样本,每一列是一个变量。

对于一些更高级的应用来说,我们可以直接使用这篇教程中讨论的一些对象来获得最大的灵活性。一些seaborn函数(如lmplot()/catplot()/pairplot())也隐式地使用了这些对象。很多seaborn函数是坐标轴级别的,它们仅仅针对某个特定的matplotlib Axes来绘图,而不会修改图形的属性;而在这篇教程中即将讨论到的这些方法是更高级别的函数,在被调用时,它们会创建一个新的图形,而且一般情况下对于创建过程更加严格。在某些案例中,这些函数和他们依赖的类所需要输入的参数依赖于不同的接口属性,比如在lmplot()中我们通过设置高度和宽高比(height和aspect)来控制每个子图(facet)的大小,而非直接指定整个图形的大小。这些函数在调用后都会返回这个图形对象,而且大多数对象都提供了非常方便的方法来改变绘图的方式,这些方法往往更加抽象和简单。

import seaborn as snsimport matplotlib.pyplot as pltsns.set(style='ticks')

一、条件式多图

当我们想要基于不同的数据子集来展示某个变量的分布或者多个变量之间的关系时,FacetGrid类会提供很大的帮助。一个FacetGrid图可以从三个维度来构建:row、col和hue。前两个与它返回的坐标轴数组有着之间的关联;我们可以把hue变量理解为第三个维度,就像长、宽和高一样,只不过在这里我们是用不同的颜色来体现它的。

在使用FacetGrid时,我们会通过一个pandas DataFrame以及控制图形网格的行、列和颜色的变量名称来初始化一个对象。这些维度变量(控制行、列和颜色的变量)应该是分类变量或者离散变量,然后这些变量的不同水平组合起来就构成了整个图形的每一个子图(facet,在这里可以理解为我们维度拆解的最小粒度)。比如说我们想要检验一下tips数据集中午餐和晚餐的差异。

另外,relplot()/catplot()/lmplot()内置了FacetGrid对象,绘图完成后他们都会返回这个对象,这样我们就可以进行更多的调整。

tips = sns.load_dataset('tips')g = sns.FacetGrid(tips, col='time')

150362355_1_20181224075203860

传入数据和维度变量名称会初始化一个网格,其中生成了基于matplotlib的图形和坐标轴,但是不会在这些坐标轴中画任何东西(因为我们还没告诉它们画什么)。

在这些网格中画图的主要方式是使用FacetGrid.map()方法。我们需要告诉它使用哪个绘图函数以及使用哪些(哪个)变量。我们用直方图来看下两个数据子集中小费的分布情况:

g = sns.FacetGrid(tips, col='time')g.map(plt.hist, 'tip');

150362355_2_20181224075203953

这一函数的目标是一步到位地提供一幅完整的成品图,它在完成绘图后还会对每个坐标轴添加注释。想要生成一个战士变量关系的图,只需要传递更多的变量名称进去。我们还可以提供关键字参数,它会将他们传递给绘图函数:

g = sns.FacetGrid(tips, col='sex', hue='smoker')g.map(plt.scatter, 'total_bill', 'tip', alpha=.7)g.add_legend();

150362355_3_2018122407520447

有很多选项可以传递给FacetGrid的构造函数,用以控制网格的样式:

g = sns.FacetGrid(tips, row='smoker', col='time', margin_titles=True)g.map(sns.regplot, 'size', 'total_bill', color='.3', fit_reg=False, x_jitter=.1);

150362355_4_20181224075204110

需要注意的是,margin_title参数并没有被matplotlib API提供正式支持,在某些案例中或许并不可用。比如说当图外边有图例时,它是不可用的。

图的大小是通过每张子图的高度和宽高比来控制的:

g = sns.FacetGrid(tips, col='day', height=4, aspect=.5)g.map(sns.barplot, 'sex', 'total_bill');/anaconda3/lib/python3.7/site-packages/seaborn/axisgrid.py:715: UserWarning: Using the barplot function without specifying `order` is likely to produce an incorrect plot. warnings.warn(warning)

150362355_5_20181224075204235

它默认会从DataFrame中推导分类的顺序。如果用来控制某个方面(facet:维度/轴/角度,看哪个概念能帮助你理解它,你就用哪个名字)的变量是分类变量,那么分类变量的顺序就会被使用。否则,seaborn会使用这些分类在数据集中出现的先后顺序。当然,我们完全可以通过*_order参数直接指定某个维度变量的顺序:

ordered_days = tips.day.value_counts().indexg = sns.FacetGrid(tips, row='day', row_order=ordered_days, height=1.7, aspect=4)g.map(sns.distplot, 'total_bill', hist=False, rug=True);

150362355_6_20181224075204344

我们可以指定某个seaborn调色板,也可以通过字典将hue变量中的每个分类与其对应的matplotlib颜色传递给函数(这样就可以随心所以使用大量的matplotlib支持的色彩):

pal = dict(Lunch='seagreen', Dinner='gray')g = sns.FacetGrid(tips, hue='time', palette=pal, height=5)g.map(plt.scatter, 'total_bill', 'tip', s=50, alpha=.7, linewidth=.5, edgecolor='white')g.add_legend();

150362355_7_20181224075204438

我们还可以控制hue变量的不同水平展示出来的其他样式(方面),这些在黑白色调下(比如黑白印刷图)对于提高图形的可读性尤其有用。我们需要将一个字典传递给hue_kws参数,在这个字典中,key(字典的键)是绘图函数的关键字参数名称;而value(字典的值)则是一个列表,用于存储关键字参数的取值,其中每个取值对应了hue变量的一个水平。

g = sns.FacetGrid(tips, hue='sex', palette='Set1', height=5, hue_kws={'marker': ['^', 'v']})g.map(plt.scatter, 'total_bill', 'tip', s=100, linewidth=.5, edgecolor='white')g.add_legend();

150362355_8_20181224075204532

如果某个维度变量(用于col/row/hue参数的变量,之后不再说明)具有非常多的水平(level:取值),我们可以把它们分布到不同的列,然后把它们“折叠”到不同的行中。当我们使用这种操作时,我们不能设置row变量。

attend = sns.load_dataset('attention').query('subject <= 12')g="sns.FacetGrid(attend," col='subject' ,="" col_wrap="4," height="2," ylim="(0," 10))g.map(sns.pointplot,="" 'solutions',="" 'score',="" color='.3' ,="" ci="None);/anaconda3/lib/python3.7/site-packages/seaborn/axisgrid.py:715:" userwarning:="" using="" the="" pointplot="" function="" without="" specifying="" `order`="" is="" likely="" to="" produce="" an="" incorrect="" plot.="">=>

150362355_9_20181224075204610

当我们已经使用FacetGrid.map()完成了绘图,我们可能还想对图形的某些方面做些调整。FacetGrid支持很多在更高层级调整图形的方法,最常用的是FacetGrid.set(),还有一些更加具体的方法比如FacetGrid.set_axis_labels(),如图:

with sns.axes_style('white'): g = sns.FacetGrid(tips, row='sex', col='smoker', margin_titles=True, height=2.5)g.map(plt.scatter, 'total_bill', 'tip', color='#334488', edgecolor='white', lw=.5);g.set_axis_labels('Total bill (US Dollars)', 'Tip');g.set(xticks=[10, 30, 50], yticks=[2, 6, 10]);g.fig.subplots_adjust(wspace=.02, hspace=.02);

150362355_10_20181224075204735

想要做更多定制的话,我们可以直接操作更底层的Figure和Axes对象,它们存储在FacetGrid.fig和FacetGrid.axes中,其中,FacetGrid.axes是一个二维数组。假如我们没有指定行和列,那么我们也可以直接使用FacetGrid.ax来操作那个唯一的坐标轴:

g = sns.FacetGrid(tips, col='smoker', margin_titles=True, height=4)g.map(plt.scatter, 'total_bill', 'tip', color='#338844', edgecolor='white', s=50, lw=1)for ax in g.axes.flat: ax.plot((0, 50), (0, .2 * 50), c='.2', ls='--')g.set(xlim=(0, 60), ylim=(0, 14));

150362355_11_20181224075204844

二、使用自定义绘图函数

使用FacetGrid时,我们并非只能使用现成的matplotlib和seaborn绘图函数。不过,如果想要正常工作,我们的自定义函数需要满足一下规则:它必须是一个坐标轴级别的函数(仅对当前活跃的坐标轴进行绘图)。在matplotlib.pyplot的命名空间中存在的函数都是符合要求的,我们也可以调用plt.gca()(get current axes)来获取符合要求的坐标轴。

它必须支持以位置参数的方式接受数据传入。FacetGrid内部会把我们传递给FacetGrid.map()的多组序列数据分别传递给这些位置参数。

它必须支持接受关键字参数color和label,另外,理想情况下,它还会利用这两个参数做一些有用的事情。在大多数情况下,接受一个关键字参数(**kwargs)的字典并传递给底层的绘图函数是很容易的。

我们来看一个符合最低条件的例子,这个绘图函数仅接受一组来自某个分类(子数据集)的向量型数据:

from scipy import statsdef quantile_plot(x, **kwargs): qntls, xr = stats.probplot(x, fit=False) plt.scatter(xr, qntls, **kwargs) g = sns.FacetGrid(tips, col='sex', height=4)g.map(quantile_plot, 'total_bill');

150362355_12_20181224075204922

如果我们想要绘制一个二元图,我们需要让函数接受两组数据,且x轴对应的数据在前边,y轴对应的数据在后边:

def qqplot(x, y, **kwargs): _, xr = stats.probplot(x, fit=False) _, yr = stats.probplot(y, fit=False) plt.scatter(xr, yr, **kwargs)g = sns.FacetGrid(tips, col='smoker', height=4)g.map(qqplot, 'total_bill', 'tip');

150362355_13_201812240752050

由于plt.scatter可以接受关键字参数color和label并且能正确处理它们,所以我们可以毫不费力地增加一个hue参数(因为它的原理就是给不同的分类数据传入不同的颜色参数):

g = sns.FacetGrid(tips, hue='time', col='sex', height=4)g.map(qqplot, 'total_bill', 'tip')g.add_legend();

150362355_14_2018122407520578

我们还可以通过关键字参数控制额外的美学设计来区分hue变量的不同水平:

g = sns.FacetGrid(tips, hue='time', col='sex', height=4, hue_kws={'marker': ['s', 'D']})g.map(qqplot, 'total_bill', 'tip', s=40, edgecolor='w')g.add_legend();

150362355_15_20181224075205188

当然,有时我们完全不想处理color和label。这种情况下我们需要显式地接受他们,然后用自己的逻辑去处理他们。比如下边这个使用plt.hexbin的例子,在与FacetGridAPI搭配的过程中。如果我们没有手动调整颜色处理方式的话,它们的表现会不太好:

def hexbin(x, y, color, **kwargs): cmap = sns.light_palette(color, as_cmap=True) plt.hexbin(x, y, gridsize=15, cmap=cmap, **kwargs)with sns.axes_style('white'): g = sns.FacetGrid(tips, hue='time', col='time', height=4)g.map(hexbin, 'total_bill', 'tip', extent=[0, 50, 0, 10]);

150362355_16_20181224075205313

三、展示变量间的两两(成对)关系

PairGrid也支持我们以同样的方式快速绘制多个子图。在PairGrid中,每行每列都被分配给一个不同的变量,所以最后生成的图片可以展示数据集中所有的成对关系。这种风格的图形有时被称作“散点图矩阵”,因为散点图是表现两两关系最常用的方法。不过PairGrid并不会仅仅局限于散点图。

了解FacetGrid和PairGrid之间的区别非常重要。在FacetGrid中,每张图表现的都是同样的变量关系,只是每张图对应着不同的数据子集,数据子集的划分是由我们指定的维度变量决定的(col、row和hue),这些变量相互交叉后产生一系列最小粒度的数据子集,每个子集就对应了一张子图,也就是说,不管是多少行、多少列还是多少颜色,它们都对应着这些维度变量的取值(水平)。而在PairGrid中,每张子图都代表了不同的两个变量间的关系(当然,上三角和下三角会有镜像的关系,因为它们相当于互换了x轴和y轴)。PairGrid可以对于我们数据集中的变量关系提供一个非常快速、整体(不深入)的总结。

它的基本使用方法与FacetGrid非常类似。首先我们初始化一个网格,然后把绘图函数传递给map方法,它会将我们的绘图函数在所有的子图中调用。与PairGrid对应的函数是pairplot(),它失去了一些灵活性,但是让我们的绘图更加快捷。

iris = sns.load_dataset('iris')g = sns.PairGrid(iris)g.map(plt.scatter);

150362355_17_20181224075205422

我们可以在对角线上用不同的函数来展示单变量的分布情况。不过需要注意的是,轴上的刻度与分桶计数或者密度没有关系(因为我们已经用轴刻度去展示数据的取值了)。

g = sns.PairGrid(iris)g.map_diag(plt.hist)g.map_offdiag(plt.scatter);

150362355_18_20181224075205563

在这种图中,我们常常会对属于不同分类的样本标记上不同的颜色。比如,iris数据集中有三种不同的鸢尾花,其中每个样本都有4个特征,因此我们可以看下它们的区别在哪里。

g = sns.PairGrid(iris, hue='species')g.map_diag(plt.hist)g.map_offdiag(plt.scatter)g.add_legend();

150362355_19_20181224075205719

默认情况下,数据集中所有的数值型变量都会被使用,不过我们也可以仅选用特定的列:

g = sns.PairGrid(iris, vars=['sepal_length', 'sepal_width'], hue='species')g.map(plt.scatter);

150362355_20_20181224075205860

我们也可以分别在上三角和下三角中使用不同的函数,用以强调关系的不同角度。

g = sns.PairGrid(iris)g.map_upper(plt.scatter)g.map_lower(sns.kdeplot)g.map_diag(sns.kdeplot, lw=3, legend=False);

150362355_21_20181224075205969

事实上,这种对称的方形网格矩阵只是一个特例,我们可以在行和列上分别使用不同的变量。

g = sns.PairGrid(tips, y_vars=['tip'], x_vars=['total_bill', 'size'], height=4)g.map(sns.regplot, color='.3')g.set(ylim=(-1, 11), yticks=[0, 5, 10]);

150362355_22_2018122407520678

当然,设计(美学)属性都是可以配置的。比如,我们可以使用不同的调色板、可以给绘图函数传递关键字参数。

g = sns.PairGrid(tips, hue='size', palette='GnBu_d')g.map(plt.scatter, s=50, edgecolor='white')g.add_legend();

150362355_23_20181224075206188

PairGrid很灵活,但是想要快速观察数据特点的话,使用pairplot()更容易。这个函数默认使用散点图和直方图,但是也支持一些其他类型(现在我们还可以在非对角位置上画回归图、在对角位置上画KDE图),未来还会支持更多。

sns.pairplot(iris, hue='species', height=2.5);

150362355_24_20181224075206282

在pairplot()中我们也可以通过关键字参数调整设计风格(美学),并且它会返回一个PairGrid对象用于更多的调整。

g = sns.pairplot(iris, hue='species', palette='Set2', diag_kind='kde', height=2.5)

150362355_25_20181224075206438

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/281950.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

面对峰值响应冲击,解决高并发的三大策略

2019独角兽企业重金招聘Python工程师标准>>> 当前在互联网的大潮下&#xff0c;众所周知淘宝、京东这些交易系统每天产生的数据量都是海量的&#xff0c;每天的交易并发也是惊人的&#xff0c;尤其是“双11”、“6.18”这些活动&#xff0c;对系统的峰值响应提出了非…

hibernate mysql 主从_MYSQL主从复制和写分离

基础篇https://edu.51cto.com/course/19845.htmlhttps://edu.51cto.com/course/19845.htmlhttps://edu.51cto.com/course/19841.htmlhttps://edu.51cto.com/course/21197.htmlhttps://edu.51cto.com/course/19886.htmlhttps://edu.51cto.com/course/19887.htmlhttps://edu.51ct…

全新升级的AOP框架Dora.Interception[6]: 框架设计和实现原理

本系列前面的五篇文章主要介绍Dora.Interception的编程模式以及对它的扩展定制&#xff0c;现在我们来聊聊它的设计和实现原理。目录一、调用链抽象二、基于约定的拦截器定义三、基于调用上下文的依赖注入容器四、拦截器的提供五、调用链的构建六、方法拦截的实现原理七、依赖注…

完成登录与注册页面的前端

完成登录与注册页面的HTMLCSSJS&#xff0c;其中的输入项检查包括&#xff1a; 用户名6-12位 首字母不能是数字 只能包含字母和数字 密码6-12位 注册页两次密码是否一致 JS&#xff1a; function fnLogin() {var uSer document.getElementById("user");var pAss do…

WPF效果第二百零一篇之实现合并单元格

早一段时间又一次出差青海省西宁市;回来又是总结又是各种琐事,也没顾得上去分享点东西;大周末的就在家分享一下,这二天再次基于ListBox实现的合并单元格的效果:1、ListBox嵌套ListBox的前台布局:<ListBox ItemsSource"{Binding LCPListData}" x:Name"Manufac…

ASP.NET Core中使用EasyCaching作为缓存抽象层

简介做后端开发&#xff0c;缓存应该是天天在用&#xff0c;很多时候我们的做法是写个帮助类&#xff0c;然后用到的时候调用一下。这种只适合简单层次的应用&#xff1b;一旦涉及到接口实现调整之类的&#xff0c;这种强耦合的做法很不合适。有些其他的功能又要去重复造轮子。…

visual studio开启多核编译方法

先按http://blog.csdn.net/acaiwlj/article/details/50240625的方法进行了VS多线程的启动。 原本以为按以下步骤设置就OK了&#xff0c;但是编译中无意间发些了一个warning&#xff1a;“/Gm”与多处理不兼容&#xff1b;忽略 /MP 开关&#xff01;&#xff01;&#xff01;&am…

聊聊storm nimbus的LeaderElector

为什么80%的码农都做不了架构师&#xff1f;>>> 序 本文主要研究一下storm nimbus的LeaderElector Nimbus org/apache/storm/daemon/nimbus/Nimbus.java public static void main(String[] args) throws Exception {Utils.setupDefaultUncaughtExceptionHandler();…

如果我去深圳,你会见我吗

▲图/ 深圳夜景初次见易小姐&#xff0c;还是21年的春节回老家的时候。想来20年因为疫情没有回家&#xff0c;家母几次三番电话里头表达的思念以及建议一些不靠谱的回家计划&#xff0c;着实有些不忍&#xff0c;确实有似“儿行千里母担忧”之理&#xff0c;索性拿着年假和加班…

开源轻量的 .NET 监控工具 - 看门狗

你好&#xff0c;这里是 Dotnet 工具箱&#xff0c;定期分享 Dotnet 有趣&#xff0c;实用的工具或组件&#xff0c;希望对您有用&#xff01;简介WatchDog 是一个使用 C# 开发的开源的轻量监控工具&#xff0c;它可以记录和查看 ASP.Net Core Web 和 WebApi 的实时消息、事件、…

BZOJ 3231: [Sdoi2008]递归数列 (JZYZOJ 1353) 矩阵快速幂

http://www.lydsy.com/JudgeOnline/problem.php?id3231和斐波那契一个道理在最后加一个求和即可1 #include<cstdio>2 #include<cstring>3 #include<iostream>4 //using namespace std;5 const int maxn10010;6 const double eps1e-8;7 long long modn;8 lon…

马斯克的火箭上天了,SpaceX开源项目也登上了热榜!

python知识手册SpaceX于美国东部时间5月30日下午3&#xff1a;22分将两位美国宇航员送往国际空间站&#xff0c;虽然这只是Demo任务&#xff0c;但SpaceX已经以其卓越工程优势、低廉的发射成本赢得了全球航天产业的信赖。同时也是除美俄中这些航天国家队以外&#xff0c;唯一独…

机器视觉Halcon教程(1.介绍)

前言本期教程主要教大家如何使用Halcon机器视觉&#xff0c;通过使用Halcon, 我们可以实现一些机器视觉的应用开发。例如: OCR识别、视觉定位、缺陷检测等内容。什么是halcon&#xff1f;简单来说, Halcon就是一款应用于机器视觉的软件&#xff0c;它提供了一套开发工具&#x…

网络时间的那些事及 ntpq 详解

2019独角兽企业重金招聘Python工程师标准>>> GMT (Greenwich Mean Time)格林威治时间 UTC (Coordinated Universal Time) 协调世界时 IAT (International Atomic Time),TAI 国际原子时 CST (Chinese Standard Time), 北京时间Gentoo&#xff08;也许其他发行版也是&…

【前端芝士树】Javascript的原型与原型链

【前端芝士树】Javascript的原型、原型链以及继承机制 前端的面试中经常会遇到这个问题&#xff0c;自己也是一直似懂非懂&#xff0c;趁这个机会整理一下0. 为什么会出现原型和原型链的概念 1994年&#xff0c;网景公司&#xff08;Netscape&#xff09;发布了Navigator浏览器…

C# 反射之Activator用法举例

概述程序运行时&#xff0c;通过反射可以得到其它程序集或者自己程序集代码的各种信息&#xff0c;包括类、函数、变量等来实例化它们&#xff0c;执行它们&#xff0c;操作它们&#xff0c;实际上就是获取程序在内存中的映像&#xff0c;然后基于这个映像进行各种操作。Activa…

MyBatis批量插入

转载于:https://blog.51cto.com/12701034/1929672

狐狸文│区块链发展的正路

&#xff08;图片出自网络&#xff0c;版权归原作者所有&#xff09;最近看了一本书&#xff1a;《美国增长的起落》。这本书是大部头&#xff0c;但看起来很过瘾。通过对这本书的阅读&#xff0c;我更新了自己对区块链发展的理解。这一年&#xff0c;“区块链”很热&#xff0…

Qt之水平/垂直布局(QBoxLayout、QHBoxLayout、QVBoxLayout)

简述 QBoxLayout可以在水平方向或垂直方向上排列控件&#xff0c;由QHBoxLayout、QVBoxLayout所继承。 QHBoxLayout&#xff1a;水平布局&#xff0c;在水平方向上排列控件&#xff0c;即&#xff1a;左右排列。 QVBoxLayout&#xff1a;垂直布局&#xff0c;在垂直方向上排列控…

Optaplanner终于支持多线程并行运行 - Multithreaded incremental solving

Optaplanner 7.9.0.Final之前&#xff0c;启动引擎开始对一个Problem进行规划的时候&#xff0c;只能是单线程进行的。也就是说&#xff0c;当引擎对每一个possible solution进行分数计算的过程中&#xff0c;细化到每个步骤(Caculation)&#xff0c;都只能排队在同一个线程中依…