用matplotlib和seaborn做数据可视化

数据可视化就是使用图形图表等方式来呈现数据,图形图表能够高效清晰地表达数据包含的信息。数据可视化在各个领域都得到了广泛的应用,例如,产品销售数据的可视化,统计样本数据可视化,机器学习数据可视化等。
Python有很多非常优秀易用的数据可视化的库,其中最著名的要数matplotlib了,它有着十几年的历史,至今仍然是Python使用者最常用的画图库。
Seaborn跟matplotlib最大的区别就是它的默认绘图风格和色彩搭配都具有现代美感,其实是在matplotlib的基础上进行了更高级的API封装,让你能用更少的代码去调用 matplotlib的方法,从而使得作图更加容易,在大多数情况下使用seaborn就能做出很具有吸引力的图,而使用matplotlib就能制作具有更多特色的图。应该把Seaborn视为matplotlib的补充,而不是替代物。

安装

pip install matplotlib
pip install seaborn

参数配置

matplotlib.pyplot使用rc配置文件来自定义图形的各种默认属性,称之为rc配置或rc参数。通过rc参数可以修改默认的属性,包括窗体大小、每英寸的点数、线条宽度、颜色、样式、坐标轴、坐标和网络属性、文本、字体等。
经过优化配置后图表会更美观。

#-*- coding:utf-8 -*-
import matplotlib as mpl
import matplotlib.pyplot as plt
import seaborn as sns
# 一些默认配置,使得图表更美观
large = 22; med = 16; small = 12
params = {'axes.titlesize': large,
          'legend.fontsize': med,
          'figure.figsize': (16, 10),
          'axes.labelsize': med,
          'axes.titlesize': med,
          'xtick.labelsize': med,
          'ytick.labelsize': med,
          'figure.titlesize': large}
plt.rcParams.update(params)
plt.style.use('seaborn-whitegrid')
sns.set_style("white")
# 设置matplotlib正常显示中文
plt.rcParams['font.sans-serif']=['SimHei']   # 用黑体显示中文
plt.rcParams['axes.unicode_minus']=False 

1、直方图

直方图(Histogram),又称质量分布图,是一种统计报告图,由一系列高度不等的纵向条纹或线段表示数据分布的情况。 一般用横轴表示数据类型,纵轴表示分布情况。

def plot_dist(title, x):
    '''
    绘制质量分布图
    INPUT  -> 标题, 数据集(单变量)
    '''
    plt.figure(figsize=(12,10), dpi= 80)
    sns.distplot(x, hist=True, kde=True, rug=True) # 前两个代表直方图和一元核密度估计图,默认就是True;rug是在最下方显示出频率情况,默认为False

    plt.title(title, fontsize=22)
    plt.show()


# 生成一些随机数
rs = np.random.RandomState(80)
s = pd.Series(rs.randn(70) * 100)
plot_dist('测试图', s)

2、核密度估计图

核密度估计(kernel density estimation)是在概率论中用来估计未知的密度函数,属于非参数检验方法之一。通过核密度估计图可以比较直观的看出数据样本本身的分布特征。

def plot_1kde(title, x, cumulative=False):
    '''
    绘制一元核密度估计图
    INPUT  -> 标题, 数据集(单变量)
    '''
    plt.figure(figsize=(12,10), dpi= 80)
    sns.kdeplot(x, cumulative=cumulative, shade=True, color='r') # cumulative为密度累计, shade表示线下颜色为阴影, color表示颜色是红色

    plt.title(title, fontsize=22)
    plt.show()

def plot_2kde(title, x, y):
    '''
    绘制二元核密度估计图
    INPUT  -> 标题, 字段1, 字段2
    '''
    plt.figure(figsize=(12,10), dpi= 80)
    sns.kdeplot(x, y, shade=True, cbar=True) # cbar表示颜色棒

    plt.title(title, fontsize=22)
    plt.show()

# 生成一些随机数
rs = np.random.RandomState(80)
s = pd.Series(rs.randn(70) * 100)
h = pd.Series(rs.randn(70) * 100)
plot_1kde('测试图', s)
plot_2kde('测试图2', s, h)

3、散点图

def plot_joingrid(x, y):
    '''
    绘制两个变量关系图
    INPUT  -> 字段1, 字段2
    '''
    g = sns.jointplot(x=x, y=y,  # 设置xy轴,显示columns名称
              color = 'k',   # 设置颜色
              s = 50, edgecolor="w",linewidth=1,  # 设置散点大小、边缘线颜色及宽度(只针对scatter)
              kind = 'scatter',   # 设置类型:“scatter”、“reg”、“resid”、“kde”、“hex”
              space = 0.2,  # 设置散点图和布局图的间距
              size = 5,   # 图表大小(自动调整为正方形)
              ratio = 4,  # 散点图与布局图高度比,整型
              marginal_kws=dict(bins=15, rug=True)  # 设置柱状图箱数,是否设置rug
              )  
    
    g = g.set_axis_labels("X","Y")
    plt.show()

# 生成一些随机数
rs = np.random.RandomState(80)
s = pd.Series(rs.randn(70) * 100)
h = pd.Series(rs.randn(70) * 100)
plot_joingrid(s, h)

4、分类/分簇散点图

Stripplot按照不同类别对样本数据进行分布散点图绘制。
Swarmplot也是绘制散点图,但它会通过算法,在类别坐标轴的方向上延展那些原本重合的点,与通过Stripplot.jitter属性增加抖动有异曲同工之妙。

def plot_pairgrid1(x, y):
    '''
    绘制分类散点图
    INPUT  -> 分组列, 统计列
    '''
    colors = ['#1890FF', '#2FC25B', '#FACC14', '#223273', '#8543E0', '#13C2C2', '#3436c7', '#F04864']
    sns.stripplot(x=x,   # 设置分组统计字段
                  y=y,   # 数据分布统计字段    
                  # 这里xy数据对调,会使得散点图横向分布
                  jitter=0.05,  # jitter代表设置抖动
                  edgecolor = 'w', linewidth = 1, marker = 'o',
                  palette=colors)  
    plt.show()

def plot_pairgrid2(x, y):
    '''
    绘制分簇散点图
    INPUT  -> 分组列, 统计列
    '''
    colors = ['#1890FF', '#2FC25B', '#FACC14', '#223273', '#8543E0', '#13C2C2', '#3436c7', '#F04864']
    sns.swarmplot(x=x,   # 设置分组统计字段
                  y=y,   # 数据分布统计字段    
                  # 这里xy数据对调,会使得散点图横向分布
                  edgecolor = 'w', linewidth = 1, marker = 'o',
                  palette=colors)  
    plt.show()

tips = sns.load_dataset('tips')
plot_pairgrid1(tips['day'], tips['total_bill'])
plot_pairgrid2(tips['day'], tips['total_bill'])

5、箱体图/小提琴图/LV图

通过Boxplot可以看到数据的最大值、上四分位数Q3、中位数、下四分位数Q1、最小值和异常值的分布。
Violinplot与Boxplot相似,但其图形如同小提琴般,可以更好地展现出数据的量化形态。
lvplot(信值图)是箱线图和提琴图的混合,但是对于大数据集有更强的缩放能力,渲染速度更快。

def plot_box(x, y):
    '''
    绘制箱体图
    INPUT  -> 字段1, 字段2
    '''
    sns.boxplot(x = x, y = y, 
                # data = df,
                linewidth = 2, #线宽
                width = 0.8, # 箱之间的间隔比例
                fliersize = 3, #异常点大小
                whis = 1.5,     #设置IQR
                notch = True,   #设置是否以中值做凹槽
                order = {'Thur','Fri','Sat','Sun'}, # 筛选类别
                palette='Set2'  #设置调色板
                )
    #可以添加散点图
    sns.swarmplot(x = x, y = y, color = 'k', size = 3, alpha = 0.8)
    plt.show()

def plot_violin(x, y):
    '''
    绘制小提琴图
    INPUT  -> 字段1, 字段2
    '''
    sns.violinplot(x = x, y = y, 
                # data = df,
                linewidth = 2, # 线宽
                width = 0.8, # 箱之间的间隔比例
                fliersize = 3, # 异常点大小
                whis = 1.5,     # 设置IQR
                notch = True,   # 设置是否以中值做凹槽
                scale = 'count',  # 测度小提琴图的宽度: area-面积相同,count-按照样本数量决定宽度,width-宽度一样
                order = {'Thur','Fri','Sat','Sun'}, # 筛选类别
                palette='Set2',  #设置调色板
                # hue = z,   # 按z再细分
                # split = True, # 设置是否按z拆分小提琴图
                )
    plt.show()

def plot_lv(x, y):
    '''
    绘制LV图(信值图)
    INPUT  -> 字段1, 字段2
    '''
    sns.lvplot(x = x, y = y, 
                # data = df,
                palette = 'mako',
                linewidth = 12, # 线宽
                width = 0.8, # 箱之间的间隔比例
                scale = 'area', # 设置框的大小:'linear'、'exonential'、'area'
                k_depth = 'proportion' # 设置框的数量:'proportion','tukey','trustworthy'
                )
    plt.show()

tips = sns.load_dataset('tips')
plot_box(tips['day'], tips['total_bill'])
plot_violin(tips['day'], tips['total_bill'])
plot_lv(tips['day'], tips['total_bill'])


6、矩阵图

矩阵图可以用于绘制展现数据集内多个变量之间两两关系。

def plot_pairgrid(df, mark=None):
    '''
    绘制矩阵图
    INPUT  -> 数据集, 分类标签
    '''
    g = sns.PairGrid(data=df, 
                     hue=mark)  
                     # vars=["sepal_width", "sepal_length"]  vars:需要组合的数据字段 
    g = g.map_diag(sns.kdeplot, lw=3, legend=False)   # 单变量
    # g = g.map_offdiag(plt.scatter)   
    g = g.map_upper(plt.scatter) 
    g = g.map_lower(sns.kdeplot, cmap="Blues_d")
    for ax in g.axes.flat:
        plt.setp(ax.get_xticklabels(), rotation=45)

    plt.show()

7、热力图

seaborn中的热力图,有利于数据特征的关联性表示

def plot_heatmap(title, df): 
    '''
    绘制热力图
    INPUT  -> 标题, 数据集
    '''
    plt.figure(figsize=(12,10), dpi= 80)
    sns.heatmap(df.corr(), xticklabels=df.corr().columns, yticklabels=df.corr().columns, cmap='RdYlGn', center=0, annot=True)
    
    plt.xticks(fontsize=12)
    plt.yticks(fontsize=12)
    plt.title(title, fontsize=22)
    plt.show()

6、时序图

def plot_timeseries(x, y, title, df): 
    '''
    绘制时序图
    INPUT  -> 时间字段, 数量字段, 标题, 数据集
    '''
    plt.figure(figsize=(16,10), dpi= 80)
    plt.plot(x, y, data=df, color='tab:red')

    plt.ylim(0, 1000)  # y轴显示范围
    xtick_location = df.index.tolist()[::12]  # x轴取最近12个
    xtick_labels = [i[-4:] for i in df.date.tolist()[::12]]  # 年份
    plt.xticks(ticks=xtick_location, labels=xtick_labels, rotation=0, fontsize=12, horizontalalignment='center', alpha=.7)
    plt.yticks(fontsize=12, alpha=.7)
    
    plt.title(title, fontsize=22)
    plt.grid(axis='both', alpha=.3)
    # 移除边框
    plt.gca().spines["top"].set_alpha(0.0)    
    plt.gca().spines["bottom"].set_alpha(0.3)
    plt.gca().spines["right"].set_alpha(0.0)    
    plt.gca().spines["left"].set_alpha(0.3)   
    plt.show()

拓展
Matplotlib 颜色、标记、线型
matplotlib中文文档

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,117评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,328评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,839评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,007评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,384评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,629评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,880评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,593评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,313评论 1 243
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,575评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,066评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,392评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,052评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,082评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,844评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,662评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,575评论 2 270

推荐阅读更多精彩内容