使用matplotlib绘制高级图表

目录

绘制等高线图(contour())

绘制矢量场流线图(streamplot())

绘制棉棒图(stem())

绘制哑铃图

绘制甘特图

绘制人口金字塔图

绘制漏斗图

绘制桑基图(Sankey())

绘制华夫饼图


绘制等高线图(contour())

contour(X,Y, # 表示坐标点的网格数据
        Z, # 表示坐标点对应的高度数据
        levels, # 表示等高线的数量。若levels为n,则说明绘制n+1条等高线
        colors, # 表示不同高度的等高线颜色
        cmap, # 表示颜色映射表
        linewidths, # 表示等高线的宽度
        linestyle # 表示等高线的线型
        )
# 绘制等高线图

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd

plt.rcParams['font.sans-serif'] = ['KaiTi']
plt.rcParams['axes.unicode_minus'] = False
# 计算高度
def calcu_elevation(x1, y1):
    h = (1-x1/2 + x**5 + y1**3) * np.exp(-x1**2 - y1**2) # np.exp(x) 为e的x幂次方, (1-x1/2 + x**5 + y1**3) * np.exp(-x1**2 - y1**2)求高度的公式一致
    return h
# 数据
n = 256
x = np.linspace(-2, 2, n)
y = np.linspace(-2, 2, n)
# 利用meshgrid() 函数生成网格数据
x_grid, y_grid = np.meshgrid(x, y) # 将x中每一个数据和y中每一个数据组合生成很多点,然后将这些点的x坐标放入到x_grid中,y坐标放入y_grid 中,并且相应位置是对应的
# 画布
fig = plt.figure()
ax = fig.add_subplot(111)
# 绘制等高线
con = ax.contour(x_grid, y_grid, # 网格数据
                 calcu_elevation(x_grid, y_grid), # 高度
                 8,  # 等高线数量
                 colors='black' # 不同高度的等高线颜色
                 )
# 填充等高线的颜色
ax.contourf(x_grid, y_grid, # 网格数据
            calcu_elevation(x_grid, y_grid), # 高度
            8,  # 等高线数量
            alpha=0.75, # 透明度
            cmap=plt.cm.copper # 颜色映射表
           )
# 为等高线添加文字标签
ax.clabel(con, # 要标记的等高线图
          inline=True, # 删除放置标签的基础轮廓。
          fmt='%1.1f', # 标签的格式字符串
          fontsize=10 
         )
ax.set_xticks([]) # 空标签
ax.set_yticks([])
ax.set_title('等高线图')
plt.show()

使用matplotlib绘制高级图表_第1张图片

绘制矢量场流线图(streamplot())

# 常用参数
streamplot([x, y,] # 表示间距均匀的网格数据
           u, v, # 表示(x, y)速率的二维数组
           density=1, # 表示流线的密度
           linewidth=None, # 表示流线的宽度
           arrowsize, # 表示箭头的类型
           minlength, # 表示流线的最小长度
           maxlength # 表示流线的最大长度
           )
# 绘制矢量场流线图
y, x = np.mgrid[0:5:50j, 0:5:50j] # 生成两个均匀的50行50列的网格数据是二维数组
u = x
v = y
fig = plt.figure()
ax = fig.add_subplot(111)
# 绘制矢量场流线图
ax.streamplot(x, y, # 间距均匀的网格数据
              u, v, # (x, y)速率的二维数组
              density=2, # 流线的密度
             )
plt.show()

使用matplotlib绘制高级图表_第2张图片

绘制棉棒图(stem())

makerline, stemlines, baseline = \n
ax.stem([x,] y, # 表示茎的x值和茎头的y值
     linefmt=None, # 表示茎属性的字符串
     markerfmt=None, # 表示茎头属性的字符串
     basefmt=None, # 表示基线属性的字符串
     bottom=0, # 表示基线的y值
     label=None, # 表示应用于图例的标签
     use_line_collection=False # 若为True,则将棉棒图的所有线段存储到一个LineCollection类对象中;若为False,则将棉棒图的所有线段存储到列表中
     )
'''
stem()函数会返回一个形如(markertline,stemlines,basline)的元组,其中元组的第1个元素markerline为代表棉棒图标记的Line2D对象,
第2个元素stemlines为代表棉棒图线段的Line2D对象,第3个元素baseline为代表基线的Line2D对象
'''
# 绘制棉棒图
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd

plt.rcParams['font.sans-serif'] = ['KaiTi']
plt.rcParams['axes.unicode_minus'] = False

# 数据
x = np.arange(1, 16)
y = np.array([5.9, 6.2, 6.7, 7.0, 7.0, 7.1, 7.2, 7.4,
              7.5, 7.6, 7.7, 7.7, 7.7, 7.8, 7.9])
labels = np.array(['宝骏310', '宝马i3', '致享', '焕驰', '力帆530',
                   '派力奥', '悦翔V3', '乐风RV', '奥迪A1', '威驰FS',
                   '夏利N7', '启辰R30', '和悦A13RS', '致炫', '赛欧'])
# 画布
fig = plt.figure(figsize=(10, 6), dpi=80) # dpi指定每个长度单位像素量
ax = fig.add_subplot(111)
# 绘制棉棒图
makerline, stemlines, baseline = ax.stem(x, # 茎值
                                         y, # 茎头值
                                         linefmt='--', # 茎属性字符串为虚线
                                         markerfmt='o', # 茎头标记为o
                                         label='Teststem', # 图例标签
                                         use_line_collection=True # 将棉棒图的所有线段存储到一个LineCollection类对象中
                                        )
# 设置棉棒图线段的属性
# setp()函数:设置元素属性
plt.setp(stemlines, lw=1) # lw=linewidth 线宽度
# 轴和标题设置
ax.set_title('不同品牌轿车的燃料消耗量', fontdict={'size':18})
ax.set_ylabel('燃料消耗量(L/km)')
ax.set_xticks(x)
ax.set_xticklabels(labels, # x轴标签
                   rotation=60 # 标签呈60度方向
                  ) 
ax.set_ylim([0, 10])
# 无指向性注释文本
for temp_x, temp_y in zip(x, y):
    ax.text(temp_x, temp_y+0.5, # 注释文本的位置
            s='{}'.format(temp_y),  # 注释文本
            ha='center',
            va='bottom',  # 上方
            fontsize=14 # 字体大小
           )
plt.show()

使用matplotlib绘制高级图表_第3张图片

绘制哑铃图

# 绘制哑铃图
import pandas as pd
import matplotlib.lines as mlines
import matplotlib.pyplot as plt

plt.rcParams['font.sans-serif'] = ['KaiTi']
plt.rcParams['axes.unicode_minus'] = False
# 读取数据
df = pd.read_excel('./第八章data/health.xlsx')
# 处理数据
df.sort_values('pct_2014', inplace=True) # 将'pct_2014'排序 # inplace=True即替换
df.reset_index(inplace=True) # 重置索引直接生成一个新DataFrame或Series
df = df.sort_values(by='index') # 按新增列索引排序
# df['排名'] = df['index']+1
def newline(p1, p2, color='black'):
    ax = plt.gca()  # 获取当前的绘图区域
    l = mlines.Line2D([p1[0], p2[0]], [p1[1], p2[1]], color='skyblue')
    ax.add_line(l)
#     print(ax.add_line)
    return l
fig, ax = plt.subplots(1, 1, figsize=(8,6))
# 绘制散点
ax.scatter(y=df['index'], x=df['pct_2013'], # 数据点位置
           s=50, # 标记大小
           color='#0e668b', # 颜色
           alpha=0.7 # 透明度
          )
ax.scatter(y=df['index'], x=df['pct_2014'],# 数据点位置
           s=50,# 标记大小
           color='#a3c4dc', # 颜色 
           alpha=0.7 # 透明度
          )
# 绘制线条
for i, p1, p2 in zip(df['index'], df['pct_2013'], df['pct_2014']):
    newline([p1, i], [p2, i]) # 两点之间的线条距离,调用 newline方法绘制哑铃图
#     print([p1, i], [p2, i])
ax.set_title('2013年与2014年美国部分城市人口PCT指标的变化率', fontdict={'size':12})
ax.set_xlim(0, .25)
ax.set_xticks([.05, .1, .15, .20]) # 5%,10%,15%,20%
ax.set_xticklabels(['5%', '10%', '15%', '20%'])
ax.set_xlabel('变化率')
ax.set_yticks(df['index'])
ax.set_yticklabels(df['city'])
ax.grid(alpha=0.5, # 网格透明度
        axis='x' # 只生成x方轴的网格
        )
plt.show()

使用matplotlib绘制高级图表_第4张图片

绘制甘特图

# 绘制甘特图
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd

plt.rcParams['font.sans-serif'] = ['KaiTi']
plt.rcParams['axes.unicode_minus'] = False

# 数据
ticks = np.array(['报告提交','数据分析','数据录入','实地执行',
                  '问卷确定','试访','问卷设计','项目确定'])
y_data = np.arange(1,9)
x_data = np.array([0.5, 1.5, 1, 3, 0.5, 1, 1, 2])
# 画布
fig, ax = plt.subplots(1, 1)
ax.barh(y_data, # 条形的y坐标值
        x_data, # 条形图的长度
        tick_label=ticks, # 设置y轴坐标标签
        left=[7.5, 6, 5.5, 3, 3, 2, 1.5, 0], # 条形左侧x的左边,默认从0开始,即设置条形到y轴的距离
        color='#CD5C5C' # 设置条形图的颜色
        )
[ax.spines[i].set_visible(False) for i in ['top', 'right']] # 隐藏上轴脊和右轴脊ax.spines['top'].set_visible(False)
ax.set_title("任务甘特图")
ax.set_xlabel('日期')
ax.grid(alpha=0.5, axis='x')
plt.show()

使用matplotlib绘制高级图表_第5张图片

绘制人口金字塔图

# 绘制人口金字塔图
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd

plt.rcParams['font.sans-serif'] = ['KaiTi']
plt.rcParams['axes.unicode_minus'] = False

# 读数据
df = pd.read_excel('./第八章data/population.xlsx')
df_male = df.groupby(by='Gender').get_group('Male') # 性别按Male分组
list_male = df_male['Number'].values.tolist() # 取出人口数,将ndarray转换为list

df_female = df.groupby(by='Gender').get_group('Female') # 性别按Female分组
list_female = df_female['Number'].values.tolist() # 取出人口数,将ndarray转换为list
df_age = df.groupby('AgeGroup').sum() 

count = df_age.shape[0] # 10
y = np.arange(1, 11)
labels = []
for i in range(count):
    age = df_age.index[i] # 取出年龄段
    labels.append(age)
# 画布
fig = plt.figure()
ax = fig.add_subplot(111)
# 绘制人口金字塔图
ax.barh(y, # 条形的y坐标值
        list_male, # 条形图的长度
        tick_label=labels, # 设置y轴坐标标签
        label='男', # 设置图例标签
        color='#6699FF' 
        )
ax.barh(y, # 条形的y坐标值
        list_female, # 条形图的长度
        tick_label=labels, # 设置y轴坐标标签
        label='女', # 设置图例标签
        color='#CC6699'
        )
# 设置轴标签和标题
ax.set_ylabel("年龄段(岁)")
ax.set_xticks([-100000, -75000, -50000, -25000,
               0, 25000, 50000, 75000, 100000])
ax.set_xticklabels(['100000', '75000',' 50000', '25000',
                    '0', '25000', '50000', '75000', '100000'])
ax.set_xlabel("人数")
ax.set_title("某城市人口金字塔")
ax.legend() # 执行图例
plt.show()

使用matplotlib绘制高级图表_第6张图片

绘制漏斗图

# 绘制漏斗图
import numpy as np
import matplotlib.pyplot as plt

plt.rcParams['font.sans-serif'] = 'SimHei'
plt.rcParams['axes.unicode_minus'] = False

# 数据
num = 5
height = 0.5
x1 = np.array([1000, 500, 300, 200, 150])    # 各环节的客户数量
x2 = np.array((x1.max() - x1) / 2) # [  0. 250. 350. 400. 425.]

x3 = [i +j for i, j in zip(x1, x2)] # [1000.0, 750.0, 650.0, 600.0, 575.0]
x3 = np.array(x3)
y = -np.sort(-np.arange(num))  # 倒转y轴 [4 3 2 1 0]

# 标签   
labels=['访问商品', '加购物车', '生成订单', '支付订单', '完成交易']
# 画布
fig = plt.figure(figsize=(10, 8))
ax = fig.add_subplot(111)
# 绘制条形图
rects1 = ax.barh(y, # 条形的y坐标值
                 x3, # 条形图的长度
                 height, # 条形的宽度 
                 tick_label=labels, # 设置y轴坐标标签
                 color='g', # 设置条形图的颜色
                 alpha=0.5 # 透明度
                )
# 绘制辅助条形图
rects2 = ax.barh(y, # 条形的y坐标值
                 x2, # 条形图的长度
                 height, # 条形的宽度 
                 color='r', # 把r变成w也就是白色,将会消失
                 alpha=1
                 ) 
# 绘制右折线
ax.plot(x3, 
        y, 
        'black',
        alpha=0.7
        )
# 绘制左折线
ax.plot(x2,
        y,
        'black',
        alpha=0.7
        )
# 添加无指向型注释文本
notes = []
for i in range(0, len(x1)):
    notes.append('%.2f%%'%((x1[i] / x1[0]) * 100)) # 百分数
    
for rect_one, rect_two, note in zip(rects1, rects2, notes):
#   rect_one Rectangle(xy=(0, 3.75), width=1000, height=0.5, angle=0)......
#   rect_two Rectangle(xy=(0, 3.75), width=0, height=0.5, angle=0)..........
    text_x = rect_two.get_width() + (rect_one.get_width() - rect_two.get_width()) / 2 - 30 # 选取每个条形图中间的位置下30
    text_y = rect_one.get_y() + height / 2 # 选取y轴坐标加上每个条形宽度的一半
    ax.text(text_x, text_y, # 注释文本位置
            note,  # 注释文本
            fontsize=12
           )
# 隐藏轴脊和刻度
ax.set_xticks([]) # 空列表即没有值
# 隐藏所有轴脊
for direction in ['top', 'left', 'bottom', 'right']:
    ax.spines[direction].set_color('none')
ax.yaxis.set_ticks_position('none') # 隐藏y轴刻度线
plt.show()

使用matplotlib绘制高级图表_第7张图片

绘制桑基图(Sankey())

'''
from matplotlib.sankey import Sankey

1.创建桑基图
常用参数:
Sankey(ax=None, # 若不提供该参数,则会创建一个新的坐标轴
       scale=1.0, # 表示流量比例因子,用于按比例调整分支的宽度
       unit='', # 表示与流量相关的物理单位的字符串。若为None,则不会做数量标记
       gap=0.25 # 表示进入或离开顶部的分支间距,默认为0.25
       )
'''
# 例如,创建一个桑基图的代码如下:
sankey = Sankey(ax=None,gap=0.3)


'''
2.添加桑基图的选项
Sankey类对象可以调用add()方法为桑基图添加数据流量、标签等选项。add()方法的语法格式如下:
常用参数:
add(patchlabel='', # 表示位于图标中心的标签
    flows=None, # 表示流量数据的数组,其中投入数据为正值,产生数据为负值
    orientations=None, # 表示流的方向列表或用于所有流的单个方向,可以取值为0(从左侧输入、右侧输出)、1(从顶部到顶部)或-1(从底部到底部)
    labels, # 表示流的标签列表或用于所有流的单个标签
    trunklength # 表示输入组和输出组的基之间的长度
    )
'''
# 例如,为刚刚创建的桑基图sankey添加流的数据和标签,具体代码如下:
flows = [0.7, 0.3, -0.3, -0.1, -0.3, -0.1, -0.1, -0.1]
labels = ['工资', '副业', '生活', '购物', '深造', '运动', '其他', '买书']
sankey.add(flows=flows,labels=labels)

'''
Sankey类对象在添加数据之后需要调用finish()方法完成绘制,并返回包含多个桑基子图的列表。桑基子图包含以下字段:
patch:表示桑基子图的轮廓
flows:表示流量值(输入为正,输出为负)
angles:表示箭头角度的列表
tips:表示流路径的尖端或凹陷位置的数组,其中每一行是一个(x, y)
text:表示中心标签的Text实例
texts:表示流分支标签的Text实例
'''
  • 举例

'''
假设现在小明家日常生活的开支主要分为工资、副业、生活、购物、深造、运动、买书和其它几类,
且其中每项投入或产出值分别为0.7, 0.3, -0.3, -0.1, -0.3, -0.1, -0.1, -0.1。下面结合这些日常生活开支的数据绘制一个桑基图,示例代码如下:
'''

import matplotlib.pyplot as plt
from matplotlib.sankey import Sankey
plt.rcParams["font.sans-serif"] = ["SimHei"]
plt.rcParams["axes.unicode_minus"] = False
# 消费收入与支出数据
flows = [0.7, 0.3, -0.3, -0.1, -0.3, -0.1, -0.1, -0.1]
# 流的标签列表
labels = ["工资", "副业", "生活", "购物", "深造", "运动", "其他", "买书"]
# 流的方向
orientations = [1, 1, 0, -1, 1, -1, 1, 0]
# 创建 Sankey 类对象
sankey = Sankey()
# 为桑基图添加数据
sankey.add(flows=flows,                     # 收入与支出数据
           labels=labels,                   # 数据标签
           orientations=orientations,       # 标签显示的方向
           color="black",                   # 边缘线条颜色
           fc="lightgreen",                 # 填充颜色
           patchlabel="生活消费 ",          # 图表中心的标签
           alpha=0.7)                       # 透明度
# 桑基图绘制完成的对象
diagrams = sankey.finish()
diagrams[0].texts[4].set_color("r")         # 将下标为 4 的数据标签设为红色
diagrams[0].texts[4].set_weight("bold")     # 将下标为 4 的数据标签设为字体加粗
diagrams[0].text.set_fontsize(20)           # 将中心标签的字体大小设为20
diagrams[0].text.set_fontweight("bold")     # 将中心标签的字体设为加粗
plt.title("日常生活开支的桑基图")
plt.show()

使用matplotlib绘制高级图表_第8张图片

绘制华夫饼图

'''
pywaffle的安装
开发者可以直接使用pip命令安装pywaffle包。
打开命令提示符工具,在提示符的后面输入命令:pip install pywaffle
以上命令执行后,若命令提示符窗口出现如下字样,说明pywaffle包安装完成:
Installing collected packages: pywaffle
Successfully installed pywaffle-0.4.1
安装完成后,在提示符的后面输入python,之后输入如下导入语句进行验证:
from pywaffle import Waffle
执行以上语句后,若命令提示符窗口没有出现任何错误信息,说明pywaffle安装成功,否则说明安装失败。
'''
'''
pywaffle的使用
pywaffle是Python中专门绘制华夫饼图的包,它提供了一个继承自Figure的子类Waffle,
通过将Waffle类传递给figure()函数的FigureClass参数即可创建一个华夫饼图。

FigureClass:可以是Figure类或Figure子类。
rows:表示华夫饼图的行数。
columns:表示华夫饼图的列数。
values:表示数据,可以接收数组或字典。若values参数接收一个字典,则将字典的键作为华夫饼图的图例项。
colors:表示每个分类数据的颜色列表。
vertical:表示是否按垂直方向绘制华夫饼图,默认为False。
title:表示标题,可以接收一个字典,其中字典的键为title()函数的关键字参数。
legend:表示图例,可以接收一个字典,其中字典的键为legend()函数的关键字参数。
'''
# 例如,创建一个10行10列的华夫饼图,具体代码如下:
plt.figure(FigureClass=Waffle,  # 指定画布类为Waffle
           rows=10, # 行数设为10
           columns=10, # 列数设为10
           values=[45, 55], # 一组数据
           )
  • 举例

'''
pywaffle的使用
pywaffle是Python中专门绘制华夫饼图的包,它提供了一个继承自Figure的子类Waffle,
通过将Waffle类传递给figure()函数的FigureClass参数即可创建一个华夫饼图。

FigureClass:可以是Figure类或Figure子类。
rows:表示华夫饼图的行数。
columns:表示华夫饼图的列数。
values:表示数据,可以接收数组或字典。若values参数接收一个字典,则将字典的键作为华夫饼图的图例项。
colors:表示每个分类数据的颜色列表。
vertical:表示是否按垂直方向绘制华夫饼图,默认为False。
title:表示标题,可以接收一个字典,其中字典的键为title()函数的关键字参数。
legend:表示图例,可以接收一个字典,其中字典的键为legend()函数的关键字参数。
'''
# 例如,创建一个10行10列的华夫饼图,具体代码如下:
plt.figure(FigureClass=Waffle,  # 指定画布类为Waffle
           rows=10, # 行数设为10
           columns=10, # 列数设为10
           values=[45, 55], # 一组数据
           )

使用matplotlib绘制高级图表_第9张图片

你可能感兴趣的:(python,matplotlib,可视化,matplotlib,python)