2020-05-14 第六章 Python数据可视化

内容目录

[TOC]

01 离散型变量的可视化

饼图的绘制

  • 饼图属于最传统的统计图形之一,几乎随处可见,例如大型公司的屏幕墙、各种年度论坛的演示稿以及各大媒体发布的数据统计报告等;
  • 饼图是将一个圆分割成不同大小的楔(扇)形,而圆中的每一个楔形代表了不同的类别值,通常根据楔形的面积大小来判断类别值的差异;

饼图的绘制方法

pie(x, explode=None, labels=None, colors=None, autopct=None, pctdistance=0.6,
      shadow=False,  labeldistance=1.1, startangle=None, radius=None, 
      counterclock=True, wedgeprops=None, textprops=None, center=(0, 0), frame=False)

x:指定绘图的数据
explode:指定饼图某些部分的突出显示,即呈现爆炸式
labels:为饼图添加标签说明,类似于图例说明
colors:指定饼图的填充色
autopct:自动添加百分比显示,可以采用格式化的方法显示
pctdistance:设置百分比标签与圆心的距离
shadow:是否添加饼图的阴影效果
labeldistance:设置各扇形标签(图例)与圆心的距离
startangle:设置饼图的初始摆放角度
radius:设置饼图的半径大小
counterclock:是否让饼图按逆时针顺序呈现
wedgeprops:设置饼图内外边界的属性,如边界线的粗细、颜色等
textprops:设置饼图中文本的属性,如字体大小、颜色等
center:指定饼图的中心点位置,默认为原点
frame:是否要显示饼图背后的图框,如果设置为True的话,需要同时控制图框x轴、y轴的范围和饼图的中心位置

饼图的绘制示例

# 饼图的绘制
# 导入第三方模块
import matplotlib.pyplot as plt

# 构造数据
edu = [0.2515,0.3724,0.3336,0.0368,0.0057]
labels = ['Technical secondary school','College','Undergraduate',"master's degree",'others']

# 绘制饼图
plt.pie(x = edu, # 绘图数据
        labels=labels, # 添加教育水平标签
        autopct='%.1f%%' # 设置百分比的格式,这里保留一位小数
       )
# 添加图标题
plt.title('Distribution of education levels of untrustworthy users')
# 显示图形
plt.show()
output_1_0.png
# 添加修饰的饼图 
explode = [0,0.1,0,0,0]  # 生成数据,用于突出显示大专学历人群
colors=['#9999ff','#ff9999','#7777aa','#2442aa','#dd5555']  # 自定义颜色

# 中文乱码和坐标轴负号的处理
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
plt.rcParams['axes.unicode_minus'] = False

# 将横、纵坐标轴标准化处理,确保饼图是一个正圆,否则为椭圆
plt.axes(aspect='equal')
# 绘制饼图
plt.pie(x = edu, # 绘图数据
        explode=explode, # 突出显示大专人群
        labels=labels, # 添加教育水平标签
        colors=colors, # 设置饼图的自定义填充色
        autopct='%.1f%%', # 设置百分比的格式,这里保留一位小数
        pctdistance=0.8,  # 设置百分比标签与圆心的距离
        labeldistance = 1.1, # 设置教育水平标签与圆心的距离
        startangle = 180, # 设置饼图的初始角度
        radius = 1.2, # 设置饼图的半径
        counterclock = False, # 是否逆时针,这里设置为顺时针方向
        wedgeprops = {'linewidth': 1.5, 'edgecolor':'green'},# 设置饼图内外边界的属性值
        textprops = {'fontsize':10, 'color':'black'}, # 设置文本标签的属性值
        )

# 添加图标题
plt.title('Distribution of education levels of untrustworthy users')
# 显示图形
plt.show()
findfont: Font family ['sans-serif'] not found. Falling back to DejaVu Sans.
findfont: Font family ['sans-serif'] not found. Falling back to DejaVu Sans.
output_1_1.png
# 导入第三方模块
import pandas as pd
# 构建序列
data1 = pd.Series({'Technical secondary school':0.2515,'College':0.3724,'Undergraduate':0.3336,"master's degree":0.0368,'others':0.0057})
# 将序列的名称设置为空字符,否则绘制的饼图左边会出现None这样的字眼
data1.name = ''
# 控制饼图为正圆
plt.axes(aspect = 'equal')
# plot方法对序列进行绘图
data1.plot(kind = 'pie', # 选择图形类型
           autopct='%.1f%%', # 饼图中添加数值标签
           radius = 1, # 设置饼图的半径
           startangle = 180, # 设置饼图的初始角度
           counterclock = False, # 将饼图的顺序设置为顺时针方向
           title = 'Distribution of education levels of untrustworthy users', # 为饼图添加标题
           wedgeprops = {'linewidth': 1.5, 'edgecolor':'green'}, # 设置饼图内外边界的属性值
           textprops = {'fontsize':10, 'color':'black'} # 设置文本标签的属性值
          )
# 显示图形
plt.show()
output_2_0.png

条形图的绘制

  • 虽然饼图可以很好地表达离散型变量在各水平上的差异,但其不擅长对比差异不大或水平值过多的离散型变量,因为饼图是通过各扇形面积的大小来比价差异的,面积的比较有时并不直观;
  • 对于条形图而言,对比的是柱形的高低,柱体越高,代表的数值越大,反之亦然;

条形图的绘制方法

bar(x, height, width=0.8, bottom=None, color=None, edgecolor=None, 
       linewidth=None, tick_label=None, xerr=None, yerr=None, 
       label = None, ecolor=None, align, log=False, **kwargs)

x:传递数值序列,指定条形图中x轴上的刻度值
height:传递数值序列,指定条形图y轴上的高度
width:指定条形图的宽度,默认为0.8
bottom:用于绘制堆叠条形图
color:指定条形图的填充色
edgecolor:指定条形图的边框色
linewidth:指定条形图边框的宽度,如果指定为0,表示不绘制边框
tick_label:指定条形图的刻度标签
xerr:如果参数不为None,表示在条形图的基础上添加误差棒
yerr:参数含义同xerr
label:指定条形图的标签,一般用以添加图例
ecolor:指定条形图误差棒的颜色
align:指定x轴刻度标签的对齐方式,默认为center,表示刻度标签居中对齐,如果设置为edge,则表示在每个条形的左下角呈现刻度标签
log:bool类型参数,是否对坐标轴进行log变换,默认为False
**kwargs:关键字参数,用于对条形图进行其他设置,如透明度等

条形图的绘制--垂直条形图

# 条形图的绘制--垂直条形图
# 读入数据
GDP = pd.read_excel('./Province GDP 2017.xlsx')
# 设置绘图风格(不妨使用R语言中的ggplot2风格)
plt.style.use('ggplot')
# 绘制条形图
plt.bar(x = range(GDP.shape[0]), # 指定条形图x轴的刻度值
        height = GDP.GDP, # 指定条形图y轴的数值
        tick_label = GDP.Province, # 指定条形图x轴的刻度标签
        color = 'steelblue', # 指定条形图的填充色
       )
# 添加y轴的标签
plt.ylabel('GDP (trillions)')
# 添加条形图的标题
plt.title('Distribution of GDP of 6 provinces in 2017')
# 为每个条形图添加数值标签
for x,y in enumerate(GDP.GDP):
    plt.text(x,y+0.1,'%s' %round(y,1),ha='center')
# 显示图形    
plt.show()
output_3_1.png

条形图的绘制--水平条形图

# 条形图的绘制--水平条形图
# 对读入的数据作升序排序
GDP.sort_values(by = 'GDP', inplace = True)
# 绘制条形图
plt.barh(y = range(GDP.shape[0]), # 指定条形图y轴的刻度值
        width = GDP.GDP, # 指定条形图x轴的数值
        tick_label = GDP.Province, # 指定条形图y轴的刻度标签
        color = 'steelblue', # 指定条形图的填充色
       )
# 添加x轴的标签
plt.xlabel('GDP (trillions)')
# 添加条形图的标题
plt.title('Distribution of GDP of 6 provinces in 2017')
# 为每个条形图添加数值标签
for y,x in enumerate(GDP.GDP):
    plt.text(x+0.1,y,'%s' %round(x,1),va='center')
# 显示图形    
plt.show()
output_4_0.png

条形图的绘制--堆叠条形图

# 条形图的绘制--堆叠条形图
# 读入数据
Industry_GDP = pd.read_excel('./Industry_GDP.xlsx')
# 取出四个不同的季度标签,用作堆叠条形图x轴的刻度标签
Quarters = Industry_GDP.Quarter.unique()
# 取出第一产业的四季度值
Industry1 = Industry_GDP.GPD[Industry_GDP.Industry_Type == '第一产业']
# 重新设置行索引
Industry1.index = range(len(Quarters))
# 取出第二产业的四季度值
Industry2 = Industry_GDP.GPD[Industry_GDP.Industry_Type == '第二产业']
# 重新设置行索引
Industry2.index = range(len(Quarters))
# 取出第三产业的四季度值
Industry3 = Industry_GDP.GPD[Industry_GDP.Industry_Type == '第三产业']

# 绘制堆叠条形图
# 各季度下第一产业的条形图
plt.bar(x = range(len(Quarters)), height=Industry1, color = 'steelblue', label = 'primary industry', tick_label = Quarters)
# 各季度下第二产业的条形图
plt.bar(x = range(len(Quarters)), height=Industry2, bottom = Industry1, color = 'green', label = 'Secondary industry')
# 各季度下第三产业的条形图
plt.bar(x = range(len(Quarters)), height=Industry3, bottom = Industry1  + Industry2, color = 'red', label = 'Tertiary Industry')
# 添加y轴标签
plt.ylabel('Total value generated (100 million)')
# 添加图形标题
plt.title('Total value of tertiary industry in each quarter of 2017')
# 显示各产业的图例
plt.legend()
# 显示图形
plt.show()
output_5_0.png

条形图的绘制--水平交错条形图

# 条形图的绘制--水平交错条形图
# 导入第三方模块
import numpy as np
# 读入数据
HuRun = pd.read_excel('../第5章 Python数据处理工具--Pandas/HuRun.xlsx')
# 取出城市名称
Cities = HuRun.City.unique()
# 取出2016年各城市亿万资产家庭数
Counts2016 = HuRun.Counts[HuRun.Year == 2016]
# 取出2017年各城市亿万资产家庭数
Counts2017 = HuRun.Counts[HuRun.Year == 2017]

# 绘制水平交错条形图
bar_width = 0.4
plt.bar(x = np.arange(len(Cities)), height = Counts2016, label = '2016', color = 'steelblue', width = bar_width)
plt.bar(x = np.arange(len(Cities))+bar_width, height = Counts2017, label = '2017', color = 'indianred', width = bar_width)
# 添加刻度标签(向右偏移0.225)
plt.xticks(np.arange(5)+0.2, Cities)
# 添加y轴标签
plt.ylabel('Hundreds of millions of assets')
# 添加图形标题
plt.title('Comparison of the number of households with HMA in five cities in the past two years')
# 添加图例
plt.legend()
# 显示图形
plt.show()
output_6_0.png

Pandas模块之垂直或水平条形图

# Pandas模块之垂直或水平条形图
# 绘图(此时的数据集在前文已经按各省GDP做过升序处理)
GDP.GDP.plot(kind = 'bar', width = 0.8, rot = 0, color = 'steelblue', title = 'Distribution of GDP of 6 provinces in 2017')
# 添加y轴标签
plt.ylabel('GDP (trillions)')
# 添加x轴刻度标签
plt.xticks(range(len(GDP.Province)), #指定刻度标签的位置  
           GDP.Province # 指出具体的刻度标签值
          )
# 为每个条形图添加数值标签
for x,y in enumerate(GDP.GDP):
    plt.text(x-0.1,y+0.2,'%s' %round(y,1),va='center')
# 显示图形
plt.show()
output_7_0.png

Pandas模块之水平交错条形图

# Pandas模块之水平交错条形图
HuRun_reshape = HuRun.pivot_table(index = 'City', columns='Year', values='Counts').reset_index()
# 对数据集降序排序
HuRun_reshape.sort_values(by = 2016, ascending = False, inplace = True)
HuRun_reshape.plot(x = 'City', y = [2016,2017], kind = 'bar', color = ['steelblue', 'indianred'], 
                   rot = 0, # 用于旋转x轴刻度标签的角度,0表示水平显示刻度标签
                   width = 0.8, title = 'Comparison of the number of households with HMA in five cities in the past two years')
# 添加y轴标签
plt.ylabel('Hundreds of millions of assets')
plt.xlabel('')
plt.show()
output_8_0.png

seaborn模块之垂直或水平条形图

# seaborn模块之垂直或水平条形图
# 导入第三方模块
import seaborn as sns
sns.barplot(y = 'Province', # 指定条形图x轴的数据
            x = 'GDP', # 指定条形图y轴的数据
            data = GDP, # 指定需要绘图的数据集
            color = 'steelblue', # 指定条形图的填充色
            orient = 'horizontal' # 将条形图水平显示
           )
# 重新设置x轴和y轴的标签
plt.xlabel('GDP (trillions)')
plt.ylabel('')
# 添加图形的标题
plt.title('Distribution of GDP of 6 provinces in 2017')
# 为每个条形图添加数值标签
for y,x in enumerate(GDP.GDP):
    plt.text(x,y,'%s' %round(x,1),va='center')
# 显示图形
plt.show()
output_9_1.png
# 读入数据
Titanic = pd.read_csv('./titanic_train.csv')
# 绘制水平交错条形图
sns.barplot(x = 'Pclass', # 指定x轴数据
            y = 'Age', # 指定y轴数据
            hue = 'Sex', # 指定分组数据
            data = Titanic, # 指定绘图数据集
            palette = 'RdBu', # 指定男女性别的不同颜色
            errcolor = 'blue', # 指定误差棒的颜色
            errwidth=2, # 指定误差棒的线宽
            saturation = 1, # 指定颜色的透明度,这里设置为无透明度
            capsize = 0.05 # 指定误差棒两端线条的宽度
           )
# 添加图形标题
plt.title('Age differences between male and female passengers in each cabin class')
# 显示图形
plt.show()
output_10_0.png

02 数值型变量的可视化

直方图与密度曲线

直方图与核密度曲线绘制方法

plt.hist(x, bins=10, range=None, normed=False, weights=None, cumulative=False, 
            bottom=None, histtype='bar', align='mid', orientation='vertical', 
            rwidth=None, log=False, color=None, label=None, stacked=False)

x:指定要绘制直方图的数据。
bins:指定直方图条形的个数。
range:指定直方图数据的上下界,默认包含绘图数据的最大值和最小值。
normed:是否将直方图的频数转换成频率。
weights:该参数可为每一个数据点设置权重。
cumulative:是否需要计算累计频数或频率。
bottom:可以为直方图的每个条形添加基准线,默认为0。
histtype:指定直方图的类型,默认为bar,除此之外,还有barstacked、step和stepfilled。
align:设置条形边界值的对齐方式,默认为mid,另外还有left和right
orientation:设置直方图的摆放方向,默认为垂直方向
rwidth:设置直方图条形的宽度
log:是否需要对绘图数据进行log变换
color:设置直方图的填充色
edgecolor:设置直方图边框色
label:设置直方图的标签,可通过legend展示其图例
stacked:当有多个数据时,是否需要将直方图呈堆叠摆放,默认水平摆放

直方图与核密度曲线示例

# matplotlib模块绘制直方图
# 检查年龄是否有缺失
any(Titanic.Age.isnull())
# 不妨删除含有缺失年龄的观察
Titanic.dropna(subset=['Age'], inplace=True)
# 绘制直方图
plt.hist(x = Titanic.Age, # 指定绘图数据
         bins = 20, # 指定直方图中条块的个数
         color = 'steelblue', # 指定直方图的填充色
         edgecolor = 'black' # 指定直方图的边框色
         )
# 添加x轴和y轴标签
plt.xlabel('Age')
plt.ylabel('Frequency')
# 添加标题
plt.title('Passenger age distribution')
# 显示图形
plt.show()
output_11_0.png
Titanic.Age.plot(kind = 'kde', color = 'red', label = 'density')
<matplotlib.axes._subplots.AxesSubplot at 0x115106310>
output_12_1.png
# Pandas模块绘制直方图和核密度图
# 绘制直方图
sns.distplot(Titanic.Age)
<matplotlib.axes._subplots.AxesSubplot at 0x126cecc40>
output_13_1.png
# seaborn模块绘制分组的直方图和核密度图
# 取出男性年龄
Age_Male = Titanic.Age[Titanic.Sex == 'male']
# 取出女性年龄
Age_Female = Titanic.Age[Titanic.Sex == 'female']

# 绘制男女乘客年龄的直方图
sns.distplot(Age_Male, bins = 20, kde = False, hist_kws = {'color':'steelblue'}, label = 'male')
# 绘制女性年龄的直方图
sns.distplot(Age_Female, bins = 20, kde = False, hist_kws = {'color':'purple'}, label = 'female')
plt.title('Age histogram of male and female passengers')
# 显示图例
plt.legend()
# 显示图形
plt.show()

# 绘制男女乘客年龄的核密度图
sns.distplot(Age_Male, hist = False, kde_kws = {'color':'red', 'linestyle':'-'}, 
             norm_hist = True, label = 'male')
# 绘制女性年龄的核密度图
sns.distplot(Age_Female, hist = False, kde_kws = {'color':'black', 'linestyle':'--'}, 
             norm_hist = True, label = 'female')
plt.title('Age density map of male and female passengers')
# 显示图例
plt.legend()
# 显示图形
plt.show()
output_14_0.png
output_14_1.png

箱线图的绘制

  • 箱线图是另一种体现数据分布的图形,通过该图可以得知数据的下须值(Q1-1.5IQR)、下四分位数(Q1)、中位数(Q2)、均值、上四分位(Q3)数和上须值(Q3+1.5IQR),更重要的是,箱线图还可以发现数据中的异常点;

箱线图的绘制方法

plt.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:bool类型参数,是否填充箱体的颜色;默认为False
meanline:bool类型参数,是否用线的形式表示均值,默认为False
showmeans:bool类型参数,是否显示均值,默认为False
showcaps:bool类型参数,是否显示箱线图顶端和末端的两条线(即上下须),默认为True
showbox:bool类型参数,是否显示箱线图的箱体,默认为True
showfliers:是否显示异常值,默认为True
boxprops:设置箱体的属性,如边框色,填充色等
labels:为箱线图添加标签,类似于图例的作用
filerprops:设置异常值的属性,如异常点的形状、大小、填充色等
medianprops:设置中位数的属性,如线的类型、粗细等
meanprops:设置均值的属性,如点的大小、颜色等
capprops:设置箱线图顶端和末端线条的属性,如颜色、粗细等
whiskerprops:设置须的属性,如颜色、粗细、线的类型等

绘制箱线图示例

# 读取数据
Sec_Buildings = pd.read_excel('./sec_buildings.xlsx')
# 绘制箱线图
plt.boxplot(x = Sec_Buildings.price_unit, # 指定绘图数据
            patch_artist=True, # 要求用自定义颜色填充盒形图,默认白色填充
            showmeans=True, # 以点的形式显示均值
            boxprops = {'color':'black','facecolor':'steelblue'}, # 设置箱体属性,如边框色和填充色
            # 设置异常点属性,如点的形状、填充色和点的大小
            flierprops = {'marker':'o','markerfacecolor':'red', 'markersize':3}, 
            # 设置均值点的属性,如点的形状、填充色和点的大小
            meanprops = {'marker':'D','markerfacecolor':'indianred', 'markersize':4}, 
            # 设置中位数线的属性,如线的类型和颜色
            medianprops = {'linestyle':'--','color':'orange'}, 
            labels = [''] # 删除x轴的刻度标签,否则图形显示刻度标签为1
           )
# 添加图形标题
plt.title('Boxplot of price distribution in second-hand houses')
# 显示图形
plt.show()
output_15_0.png
# 二手房在各行政区域的平均单价
group_region = Sec_Buildings.groupby('region')
avg_price = group_region.aggregate({'price_unit':np.mean}).sort_values('price_unit', ascending = False)

# 通过循环,将不同行政区域的二手房存储到列表中
region_price = []
for region in avg_price.index:
    region_price.append(Sec_Buildings.price_unit[Sec_Buildings.region == region])
# 绘制分组箱线图
plt.boxplot(x = region_price, 
            patch_artist=True,
            labels = avg_price.index, # 添加x轴的刻度标签
            showmeans=True, 
            boxprops = {'color':'black', 'facecolor':'steelblue'}, 
            flierprops = {'marker':'o','markerfacecolor':'red', 'markersize':3}, 
            meanprops = {'marker':'D','markerfacecolor':'indianred', 'markersize':4},
            medianprops = {'linestyle':'--','color':'orange'}
           )
# 添加y轴标签
plt.ylabel('Unit (yuan)')
# 添加标题
plt.title('Comparison prices of second-hand houses in different administrative regions')
# 显示图形
plt.show()
output_16_1.png
# 绘制分组箱线图
sns.boxplot(x = 'region', y = 'price_unit', data = Sec_Buildings, 
            order = avg_price.index, showmeans=True,color = 'steelblue',
            flierprops = {'marker':'o','markerfacecolor':'red', 'markersize':3}, 
            meanprops = {'marker':'D','markerfacecolor':'indianred', 'markersize':4},
            medianprops = {'linestyle':'--','color':'orange'}
           )
# 更改x轴和y轴标签
plt.xlabel('')
plt.ylabel('Unit (yuan)')
# 添加标题
plt.title('Comparison prices of second-hand houses in different administrative regions')
# 显示图形
plt.show()

output_17_1.png

小提琴图的绘制示例

# 读取数据
tips = pd.read_csv('./tips.csv')
# 绘制分组小提琴图
sns.violinplot(x = "total_bill", # 指定x轴的数据
               y = "day", # 指定y轴的数据
               hue = "sex", # 指定分组变量
               data = tips, # 指定绘图的数据集
               order = ['Thur','Fri','Sat','Sun'], # 指定x轴刻度标签的顺序
               scale = 'count', # 以男女客户数调节小提琴图左右的宽度
               split = True, # 将小提琴图从中间割裂开,形成不同的密度曲线;
               palette = 'RdBu' # 指定不同性别对应的颜色(因为hue参数为设置为性别变量)
              )
# 添加图形标题
plt.title('Daily consumption of customers of different genders')
# 设置图例
plt.legend(loc = 'upper center', ncol = 2)
# 显示图形
plt.show()
output_18_0.png

折线图的绘制

  • 对于时间序列数据而言,一般都会使用折线图反映数据背后的趋势。通常折线图的横坐标指代日期数据,纵坐标代表某个数值型变量,当然还可以使用第三个离散变量对折线图进行分组处理;

折线图的绘制方法

plt.plot(x, y, linestyle, linewidth, color, marker,markersize, markeredgecolor,
            markerfactcolor,markeredgewidth, label, alpha)

x:指定折线图的x轴数据
y:指定折线图的y轴数据
linestyle:指定折线的类型,可以是实线、虚线、点虚线、点点线等,默认为实线
linewidth:指定折线的宽度
marker:可以为折线图添加点,该参数是设置点的形状
markersize:设置点的大小
markeredgecolor:设置点的边框色
markerfactcolor:设置点的填充色
markeredgewidth:设置点的边框宽度
label:为折线图添加标签,类似于图例的作用

折线图的绘制示例

# 数据读取
wechat = pd.read_excel('./wechat.xlsx')
# 绘制单条折线图
plt.plot(wechat.Date, # x轴数据
         wechat.Counts, # y轴数据
         linestyle = '-', # 折线类型
         linewidth = 2, # 折线宽度
         color = 'steelblue', # 折线颜色
         marker = 'o', # 折线图中添加圆点
         markersize = 6, # 点的大小
         markeredgecolor='black', # 点的边框色
         markerfacecolor='brown') # 点的填充色
# 添加y轴标签
plt.ylabel('Number of people')
# 添加图形标题
plt.title('Daily WeChat article readers and trends')
# 为了避免x轴刻度标签的紧凑,将刻度标签旋转45度
plt.xticks(rotation=45)
# 显示图形
plt.show()
output_19_0.png
# 绘制两条折线图
# 导入模块,用于日期刻度的修改
import matplotlib as mpl
# 绘制阅读人数折线图
plt.plot(wechat.Date, # x轴数据
         wechat.Counts, # y轴数据
         linestyle = '-', # 折线类型,实心线
         color = 'steelblue', # 折线颜色
         label = 'Readers'
         )
# 绘制阅读人次折线图
plt.plot(wechat.Date, # x轴数据
         wechat.Times, # y轴数据
         linestyle = '--', # 折线类型,虚线
         color = 'indianred', # 折线颜色
         label = 'Reading times'
         )

# 获取图的坐标信息
ax = plt.gca()
# 设置日期的显示格式  
date_format = mpl.dates.DateFormatter("%m-%d")  
ax.xaxis.set_major_formatter(date_format) 
# 设置x轴显示多少个日期刻度
# xlocator = mpl.ticker.LinearLocator(10)
# 设置x轴每个刻度的间隔天数
xlocator = mpl.ticker.MultipleLocator(7)
ax.xaxis.set_major_locator(xlocator)
# 为了避免x轴刻度标签的紧凑,将刻度标签旋转45度
plt.xticks(rotation=45)

# 添加y轴标签
plt.ylabel('Number of people')
# 添加图形标题
plt.title('Daily WeChat article readers and trends')
# 添加图例
plt.legend()
# 显示图形
plt.show()
output_20_0.png
# 读取天气数据
weather = pd.read_excel('./weather.xlsx')
# 统计每月的平均最高气温
data = weather.pivot_table(index = 'month', columns='year', values='high')
# 绘制折线图
data.plot(kind = 'line', 
          style = ['-','--',':'] # 设置折线图的线条类型
         )
# 修改x轴和y轴标签
plt.xlabel('month')
plt.ylabel('temperature')
# 添加图形标题
plt.title('Monthly average maximum temperature fluctuation trend')
# 显示图形
plt.show()
output_21_0.png

线的类型与点的形状

符号 含义 符号 含义
-(一个减号) 实心线 --(两个减号) 虚线
-.(减句号) 虚线和点构成的线 :(英文冒号) 点构成的线
.(英文句号) 实心点 o(小写字母) 空心点
^ 朝上的空心三角形 v(小写字母) 朝下的空心三角形
>(大于号) 朝右的空心三角形 <(小于号) 朝左的空心三角形
s(小写字母) 空心正方形 p(小写字母) 空心五边形
* 空心五角星 h(小写字母) 空心六边形
x(小写字母) 叉号 d(小写字母) 空心菱形

03 关系型变量的可视化

散点图的绘制

  • 如果需要研究两个数值型变量之间是否存在某种关系,例如正向的线性关系,或者是趋势性的非线性关系,那么散点图将是最佳的选择;

散点图的绘制方法

scatter(x, y, s=20, c=None, marker='o', cmap=None, norm=None, vmin=None, 
        vmax=None, alpha=None, linewidths=None, edgecolors=None)

x:指定散点图的x轴数据
y:指定散点图的y轴数据
s:指定散点图点的大小,默认为20,通过传入其他数值型变量,可以实现气泡图的绘制
c:指定散点图点的颜色,默认为蓝色,也可以传递其他数值型变量,通过cmap参数的色阶表示数值大小
marker:指定散点图点的形状,默认为空心圆
cmap:指定某个Colormap值,只有当c参数是一个浮点型数组时才有效
norm:设置数据亮度,标准化到0~1,使用该参数仍需要参数c为浮点型的数组
vmin、vmax:亮度设置,与norm类似,如果使用norm参数,则该参数无效
alpha:设置散点的透明度
linewidths:设置散点边界线的宽度
edgecolors:设置散点边界线的颜色

散点图的绘制示例

# 读入数据
iris = pd.read_csv('./iris.csv')
# 绘制散点图
plt.scatter(x = iris.Petal_Width, # 指定散点图的x轴数据
            y = iris.Petal_Length, # 指定散点图的y轴数据
            color = 'steelblue' # 指定散点图中点的颜色
           )
# 添加x轴和y轴标签
plt.xlabel('Petal_Width')
plt.ylabel('Petal_Length')
# 添加标题
plt.title('Relationship between petal width and length of iris flower')
# 显示图形
plt.show()
output_22_0.png

Pandas模块绘制散点图

# Pandas模块绘制散点图
# 绘制散点图
iris.plot(x = 'Petal_Width', y = 'Petal_Length', kind = 'scatter', title = 'Relationship between petal width and length of iris flower')
# 修改x轴和y轴标签
plt.xlabel('Petal_Width')
plt.ylabel('Petal_Length')
# 显示图形
plt.show()
output_23_0.png

seaborn模块绘制分组散点图

# seaborn模块绘制分组散点图
sns.lmplot(x = 'Petal_Width', # 指定x轴变量
           y = 'Petal_Length', # 指定y轴变量
           hue = 'Species', # 指定分组变量
           data = iris, # 指定绘图数据集
           legend_out = False, # 将图例呈现在图框内
           truncate=True # 根据实际的数据范围,对拟合线作截断操作
          )
# 修改x轴和y轴标签
plt.xlabel('Petal_Width')
plt.ylabel('Petal_Length')
# 添加标题
plt.title('Relationship between petal width and length of iris flower')
# 显示图形
plt.show()
output_24_0.png

特殊类型散点图--气泡图

  • 气泡图的实质就是通过第三个数值型变量控制每个散点的大小,点越大,代表的第三维数值越高,反之亦然;
  • 气泡图的绘制,使用的仍然是scatter函数,区别在于函数的s参数被赋予了具体的数值型变量;
# 读取数据
Prod_Category = pd.read_excel('./SuperMarket.xlsx')
# 将利润率标准化到[0,1]之间(因为利润率中有负数),然后加上微小的数值0.001
range_diff = Prod_Category.Profit_Ratio.max()-Prod_Category.Profit_Ratio.min()
Prod_Category['std_ratio'] = (Prod_Category.Profit_Ratio-Prod_Category.Profit_Ratio.min())/range_diff + 0.001

# 绘制办公用品的气泡图
plt.scatter(x = Prod_Category.Sales[Prod_Category.Category == '办公用品'], 
           y = Prod_Category.Profit[Prod_Category.Category == '办公用品'], 
           s = Prod_Category.std_ratio[Prod_Category.Category == '办公用品']*1000,
           color = 'steelblue', label = 'Office Supplies', alpha = 0.6
            )
# 绘制技术产品的气泡图
plt.scatter(x = Prod_Category.Sales[Prod_Category.Category == '技术产品'], 
           y = Prod_Category.Profit[Prod_Category.Category == '技术产品'], 
           s = Prod_Category.std_ratio[Prod_Category.Category == '技术产品']*1000,
           color = 'indianred' , label = 'Technical products', alpha = 0.6
          )
# 绘制家具产品的气泡图
plt.scatter(x = Prod_Category.Sales[Prod_Category.Category == '家具产品'], 
           y = Prod_Category.Profit[Prod_Category.Category == '家具产品'], 
           s = Prod_Category.std_ratio[Prod_Category.Category == '家具产品']*1000,
           color = 'black' , label = 'Furniture products', alpha = 0.6
          )
# 添加x轴和y轴标签
plt.xlabel('sales')
plt.ylabel('profits')
# 添加标题
plt.title('Bubble/Dotplot of sales, profits and profit margins')
# 添加图例
plt.legend()
# 显示图形
plt.show()
output_25_0.png

热图的绘制

  • 热力图也称为交叉填充表,图形最典型的用法就是实现列联表的可视化,即通过图形的方式展现两个离散变量之间的组合关系;

热力图的绘制方法

sns.heatmap(data, vmin=None, vmax=None, cmap=None, center=None, annot=None, 
                      fmt='.2g', annot_kws=None, linewidths=0, linecolor='white', cbar=True,
                      cbar_kws = None, square=False, xticklabels='auto', yticklabels='auto', 
                      mask=None, ax=None)

data:指定绘制热力图的数据集
vmin,vmax:用于指定图例中最小值与最大值的显示值
cmap:指定一个colormap对象,用于热力图的填充色
center:指定颜色中心值,通过该参数可以调整热力图的颜色深浅
annot:指定一个bool类型的值或与data参数形状一样的数组,如果为True,就在热力图的每个单元上显示数值
fmt:指定单元格中数据的显示格式
annot_kws:有关单元格中数值标签的其他属性描述,如颜色、大小等
linewidths :指定每个单元格的边框宽度
linewidths :指定每个单元格的边框宽度
linecolor:指定每个单元格的边框颜色
cbar:bool类型参数,是否用颜色条作为图例,默认为True
square:bool类型参数,是否使热力图的每个单元格为正方形,默认为False
cbar_kws:有关颜色条的其他属性描述
xticklabels,yticklabels:指定热力图x轴和y轴的刻度标签,如果为True,则分别以数据框的变量名和行名称作为刻度标签
mask:用于突出显示某些数据
ax:用于指定子图的位置

热图绘制示例

# 读取数据
Sales = pd.read_excel('./Sales.xlsx')
# 根据交易日期,衍生出年份和月份字段
Sales['year'] = Sales.Date.dt.year
Sales['month'] = Sales.Date.dt.month
# 统计每年各月份的销售总额
Summary = Sales.pivot_table(index = 'month', columns = 'year', values = 'Sales', aggfunc = np.sum)

# 绘制热力图
sns.heatmap(data = Summary, # 指定绘图数据
            cmap = 'PuBuGn', # 指定填充色
            linewidths = .1, # 设置每个单元格边框的宽度
            annot = True, # 显示数值
            fmt = '.1e' # 以科学计算法显示数据
            )
#添加标题
plt.title('Annual heatmap of total sales')
# 显示图形
plt.show()
output_26_0.png

04 多图形的组合

  • 工作中往往会根据业务需求,将绘制的多个图形组合到一个大图框内,形成类似拼图的效果;

组合图的绘制示例

# 读取数据
Prod_Trade = pd.read_excel('./Prod_Trade.xlsx')
# 衍生出交易年份和月份字段
Prod_Trade['year'] = Prod_Trade.Date.dt.year
Prod_Trade['month'] = Prod_Trade.Date.dt.month

# 设置大图框的长和高
plt.figure(figsize = (12,6))
# 设置第一个子图的布局
ax1 = plt.subplot2grid(shape = (2,3), loc = (0,0))
# 统计2012年各订单等级的数量
Class_Counts = Prod_Trade.Order_Class[Prod_Trade.year == 2012].value_counts()
Class_Percent = Class_Counts/Class_Counts.sum()
# 将饼图设置为圆形(否则有点像椭圆)
ax1.set_aspect(aspect = 'equal')
# 绘制订单等级饼图
ax1.pie(x = Class_Percent.values, labels = Class_Percent.index, autopct = '%.1f%%')
# 添加标题
ax1.set_title('Proportion of orders by level')

# 设置第二个子图的布局
ax2 = plt.subplot2grid(shape = (2,3), loc = (0,1))
# 统计2012年每月销售额
Month_Sales = Prod_Trade[Prod_Trade.year == 2012].groupby(by = 'month').aggregate({'Sales':np.sum})
# 绘制销售额趋势图
Month_Sales.plot(title = 'Monthly sales trends in 2012', ax = ax2, legend = False)
# 删除x轴标签
ax2.set_xlabel('')

# 设置第三个子图的布局
ax3 = plt.subplot2grid(shape = (2,3), loc = (0,2), rowspan = 2)
# 绘制各运输方式的成本箱线图
sns.boxplot(x = 'Transport', y = 'Trans_Cost', data = Prod_Trade, ax = ax3)
# 添加标题
ax3.set_title('Cost distribution by transport mode')
# 删除x轴标签
ax3.set_xlabel('')
# 修改y轴标签
ax3.set_ylabel('transportation cost')

# 设置第四个子图的布局
ax4 = plt.subplot2grid(shape = (2,3), loc = (1,0), colspan = 2)
# 2012年客单价分布直方图
sns.distplot(Prod_Trade.Sales[Prod_Trade.year == 2012], bins = 40, norm_hist = True, ax = ax4, hist_kws = {'color':'steelblue'}, kde_kws=({'linestyle':'--', 'color':'red'}))
# 添加标题
ax4.set_title('Distribution of customer unit prices in 2012')
# 修改x轴标签
ax4.set_xlabel('Sales')

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