Python数据处理之数据可视化(二维、三维)

一、Matplotlib绘制图形

1.1 两种画图接口:MATLAB接口、面向对象接口

MATLAB风格接口

import matplotlib.pyplot as plt

# 创建图形
fig = plt.figure()

# 创建两个子图中的第一个,设置坐标轴
plt.subplot(2,1,1) # (行、列、子图坐标)
plt.plot([1,2,3],[1,3,2])

# 创建两个子图中的第二个,设置坐标
plt.subplot(2,1,2)
plt.plot([1,2,3],[2,1,3])
# 显示图片
plt.show()

在这里插入图片描述

这接口的特性是有状态的,会持续跟踪当前的图形和坐标轴,所有plt命令都可以使用,可以用plt.gcf()获取当前图形,plt.gca()获取当前坐标轴,来查看具体信息

缺点是在做第二张图时再回到第一张图过于复杂

面向对象接口

可以适应更复杂的场景,更好的控制自己的图形,画图函数不受当前活动图形或坐标轴限制

import matplotlib.pyplot as plt

# 先创建图形网络
# ax是一个包含两个Axes对象的数组
fig, ax = plt.subplots(2)

# 在每个对象上调用plot方法
ax[0].plot([1,2,3],[1,3,2])
ax[1].plot([1,2,3],[2,3,1])

# 显示图片
plt.show()

在这里插入图片描述
画简单图时看不出效果,画复杂图时面向对象方法更方便。

绘图代码含义
fig = plt.figure()创建图形
plt.plot()绘图
fig.savefig()保存图片
plt.show()显示图片
plt.colorbar()显示颜色条

1.2 plot绘图

1.2.1 曲线图、折线图、散点图

显示空坐标

import matplotlib.pyplot as plt
import numpy as np
# 表格风格
plt.style.use('seaborn-whitegrid')
# 创建图形
fig = plt.figure()
# 坐标轴
ax = plt.axes()

# 绘图数据与绘图代码

# 显示图片
plt.show()

后面将这些代码省略了,将后面代码插入到绘图数据与绘图代码那段
在这里插入图片描述
如果没有绘图风格那行代码,画出的图不一样,后序沿用这种风格:
在这里插入图片描述
曲线图:曲线图就是点够多,各点直线连接起来,看起来就像曲线

x = np.linspace(0,10,1000)
ax.plot(x,np.sin(x))
# 可以用pylab接口画图效果一样
# plt.plot(x,np.sin(x))

在这里插入图片描述
折线图

plt.plot([1,2,3,4,5,6],[5,3,4,6,2,4])

在这里插入图片描述

一个图画多条线

x = np.linspace(0,10,1000)
plt.plot(x,np.sin(x))
plt.plot(x,np.cos(x))

在这里插入图片描述

散点图:plot添加个参数'o'

x = np.linspace(0,10,30)
plt.plot(x,np.sin(x),'o')

在这里插入图片描述
还有其他图形

# 画图
for b in ['o','.',',','x','+','v','^','<','>','s','d']:
    plt.plot(np.random.rand(2),np.random.rand(2),b,label=b)
    plt.legend()

在这里插入图片描述

1.2.2 绘图参数(线条颜色、样式)

代码说明
color参数设置线条颜色
color='blue'标准颜色名称
color='g'缩写颜色代码
color='0.75'范围在0~1的灰度值
color='#FFDD44'十六进制
color=(1.0,0.2,0.3)RGB元组,范围在0~1
color='chartreuse'HTML颜色名称
linestyle参数设置线条样式
linestyle='solid'实线
linestyle='-'同上
linestyle='dashed'虚线
linestyle='--'同上
linestyle='dashdot'点划线
linestyle='-.'同上
linestyle='dotted'实点线
linestyle=':'同上
markersize=15散点的大小
linewidth=4折线宽度
markerfacecolor='white'散点颜色
markeredgecolor='gray'散点边界颜色
markeredgewidth=2散点边界宽度
alpha=0.5透明度

灰度为0.75,样式为点划线的正弦曲线

x = np.linspace(0,10,1000)
plt.plot(x,np.sin(x),color='0.75', linestyle='dashdot')

在这里插入图片描述
参数简写

# 画图
x = np.linspace(0,10,30)
plt.plot(x,np.sin(x),'-ok') # 直线(-) 圆圈(o) 黑色(k)

在这里插入图片描述

1.2.3 散点图

该方法功能强大,与plt.plot函数类似

x = np.linspace(0,10,30)
plt.scatter(x,np.sin(x),marker='o')

在这里插入图片描述

plt.plot相比,plt.scatter创建散点图更加灵活,可以单独控制每个散点等于数据匹配,也可以让每个散点具有不同的属性(大小,表面颜色,边框颜色等)

下面创建随机散点图,里面有各种颜色和大小的散点

# 画图
x = np.random.randn(100)
y = np.random.randn(100)
colors = np.random.randn(100)
sizes = 1000*np.random.randn(100)
plt.scatter(x,y,c=colors,s=sizes,alpha=0.3,cmap='viridis')
# 显示颜色条
plt.colorbar()

在这里插入图片描述

当数据量大的时候,plt.plot的效率远远高于plt.scatter,这是因为plt.scatter会对每个点单独进行大小颜色等渲染处理

1.3 hist绘图

1.3.1 频次直方图

直方图显示数组中各个数据出现的次数

import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np

plt.style.use('seaborn-whitegrid')

# 创建图形
fig = plt.figure()
# 坐标轴
ax = plt.axes()

# 画图
plt.hist([5,8,4,6,8,2,8,2,4,1])

# 显示图片
plt.show()

在这里插入图片描述

plt.hist(np.random.randn(1000))

在这里插入图片描述

1.3.2 绘图参数

代码说明
bins=30划分块数
alpha=0.5透明度
histtype='stepfilled'风格
color='steelblue'颜色
edgecolor='none'边界颜色
plt.hist(np.random.randn(1000),bins=30,alpha=0.5,histtype='stepfilled',color='steelblue',edgecolor='none')

在这里插入图片描述

只想计算频次直方图,不要显示

counts, bin_edges = np.histogram(np.random.randint(0,10, 100), bins=5)
print(counts)
'''
[21 25 18 18 18]
'''

1.3.3 二维频次直方图

先用高斯分布生成x、y轴样本数据

mean = [0,0]
cov = [[1,1],[1,2]]
x, y = np.random.multivariate_normal(mean,cov,10000)

plt.hist2d:二维频次直方图

# 画图
mean = [0,0]
cov = [[1,1],[1,2]]
x, y = np.random.multivariate_normal(mean,cov,10000).T

plt.hist2d(x, y, bins=30, cmap='Blues')

# 显示颜色条
cb = plt.colorbar()
cb.set_label('counts in bin')

在这里插入图片描述
该方法也能实现只想计算频次直方图,不要显示

counts, xedges, yeges = np.histogram2d(x,y,bins=30)

plt.hexbin:六边形区间划分

# 画图
mean = [0,0]
cov = [[1,1],[1,2]]
x, y = np.random.multivariate_normal(mean,cov,10000).T

plt.hexbin(x, y, gridsize=30, cmap='Blues')

# 显示颜色条
cb = plt.colorbar(label='counts in bin')

在这里插入图片描述

1.4 密度图与等高线图

1.4.1 绘制等高线

先建立个函数演示等高线

def f(x, y):
    return np.sin(x) ** 10 + np.cos(10+y*x) * np.cos(x)

等高线可用plt.contour函数创建,需要三个参数:X轴、Y轴、Z轴数据
np.meshgrid函数来准备这些数据可能是最简便的,它可以从一维数组构建二维数据

import matplotlib.pyplot as plt
import numpy as np

plt.style.use('seaborn-white')

def f(x, y):
    return np.sin(x) ** 10 + np.cos(10+y*x) * np.cos(x)

x = np.linspace(0,5,50)
y = np.linspace(0,5,40)

x, y = np.meshgrid(x, y)
z = f(x,y)

plt.contour(x, y, z, colors='black')

# 显示图片
plt.show()

在这里插入图片描述

当图片只有一种颜色时,默认虚线表示负数,实线表示正数,可以用cmap参数设置一条线条配色方案来自定义颜色,还可以让更多的线条显示不同的颜色,可以将数据范围等分20份,用不同颜色表示,这里使用RdGy(红—灰,Red-Gray缩写)配色方案

plt.contour(x, y, z, 20, cmap='RdGy')

在这里插入图片描述

1.4.2 填充等高线

间隙有点大,可以用plt.contourf()填充等高线图,语法与plt.contour()一样,只是函数名多了个f,另外,可以通过plt.colorbar()自动创建一个表示图形各种颜色对应标签信息的颜色条

plt.contourf(x, y, z, 20, cmap='RdGy')
plt.colorbar()

在这里插入图片描述

1.4.3 渲染为渐变图

通过plt.imshow()可以将其渲染为渐变图,这里将x,y的数据份额变多,不然不明显

def f(x, y):
    return np.sin(x) ** 10 + np.cos(10+y*x) * np.cos(x)

x = np.linspace(0,5,500)
y = np.linspace(0,5,400)

x, y = np.meshgrid(x, y)
z = f(x,y)
plt.imshow(z,extent=[0,5,0,5], origin='lower', cmap='RdGy')
plt.colorbar()

在这里插入图片描述

plt.imshow()不支持X、Y走坐标数据,而是通过extent参数设置其范围[xmin,xmax,ymin,ymax];
plt.imshow()该函数会自动调整坐标精度,可以通过plt.axis设置x、y轴单位;
plt.imshow()该函数默认原点在左上角,而大多数在左下角

将等高线与彩色图结合起来

def f(x, y):
    return np.sin(x) ** 10 + np.cos(10+y*x) * np.cos(x)

x = np.linspace(0,5,50)
y = np.linspace(0,5,40)

x, y = np.meshgrid(x, y)
z = f(x,y)

contoues = plt.contour(x, y, z, 20, cmap='RdGy')
plt.clabel(contoues, inline=True, fontsize=8)

plt.imshow(z,extent=[0,5,0,5], origin='lower', cmap='RdGy', alpha=0.5)
plt.colorbar()

在这里插入图片描述

1.5 多子图

1.5.1 创建子图

可以创建图中图,axes里面的参数先设置两个0.65表示坐标原点位于图形高度和宽度都是65%位置,在设置两个0.2表示将坐标轴的宽度和高度设置为图形的20%

import matplotlib.pyplot as plt
import numpy as np

plt.style.use('seaborn-white')

# 创建图形
fig = plt.figure()

# 坐标轴
ax1 = plt.axes() # 默认坐标轴
ax2 = plt.axes([0.65,0.65,0.2,0.2])

# 显示图片
plt.show()

在这里插入图片描述

面向对象画图接口中类似的命令有fig.add_axes(),用和这个创建两个竖直方向的坐标轴

# 坐标轴
ax1 = fig.add_axes([0.1,0.5,0.8,0.4], xticklabels=[], ylim=(-1.2,1.2)) # 0.1 0.5为位置  0.8 0.4为比例
ax2 = fig.add_axes([0.1,0.1,0.8,0.4], xticklabels=[], ylim=(-1.2,1.2))

x = np.linspace(0, 10)
ax1.plot(np.sin(x))
ax2.plot(np.cos(x))

在这里插入图片描述

1.5.2 简易风格子图

该函数有三个参数:子图行数、列数、索引值,索引从1开始

for i in range(1,7):
    plt.subplot(2,3,i)
    plt.text(0.5,0.5,str((2,3,i)),fontsize=18,ha='center')

在这里插入图片描述

plt.subplots_adjust可以调整子图的间隔

fig.subplots_adjust(hspace=0.4, wspace=0.4)
for i in range(1,7):
    plt.subplot(2,3,i)
    plt.text(0.5,0.5,str((2,3,i)),fontsize=18,ha='center')

在这里插入图片描述

1.5.3 创建网格

如果创建大型网格子图,就要用这个方法,尤其是想要隐藏x、y轴标题时。该方法创建多个子图,返回一个包含子图的Numpy数组,关键参数是行、列、sharex、sharey
下面创建2*3网格子图,每行的3个子图同时使用相同的y坐标,每列的2个子图同时使用x坐标

import matplotlib.pyplot as plt
import numpy as np

plt.style.use('seaborn-white')

fig, ax = plt.subplots(2, 3, sharex='col', sharey='row')

# 显示图片
plt.show()

在这里插入图片描述

通过数组取值方式可以获取想要的坐标

fig, ax = plt.subplots(2, 3, sharex='col', sharey='row')

# 坐标轴存放在一个Numpy数组中,按照[roe,col]取值
for i in range(2):
    for j in range(3):
        ax[i,j].text(0.5,0.5,str((i, j)),fontsize=18, ha='center')

在这里插入图片描述

1.5.4 多子图复杂的排列方式

该方法不能直接创建一个图形,它只是plt.subplot命令可以识别的简易接口,该方法创建2*3网格后,可以通过类似Python切片的语法设置子图的位置和扩展尺寸

import matplotlib.pyplot as plt
import numpy as np

plt.style.use('seaborn-white')

grid = plt.GridSpec(2, 3, wspace=0.4, hspace=0.3)
plt.subplot(grid[0, 0])
plt.subplot(grid[0, 1:])
plt.subplot(grid[1, :2])
plt.subplot(grid[1, 2])

# 显示图片
plt.show()

在这里插入图片描述

# 创建一些正态分布数据
x = np.random.normal(1, 1, 3000)
y = np.random.normal(100, 50, 3000)

# 设置坐标轴和网格配置方式
fig = plt.figure(figsize=(6, 6))
grid = plt.GridSpec(4, 4, wspace=0.2, hspace=0.2)
main_ax = fig.add_subplot(grid[:-1,1:])
y_hist = fig.add_subplot(grid[:-1,0], xticklabels=[], sharey=main_ax)
x_hist = fig.add_subplot(grid[-1,1:], xticklabels=[], sharey=main_ax)

# 主坐标轴画散点图
main_ax.plot(x, y, 'ok', markersize=3, alpha=0.2)

# 次坐标画频次直方图
x_hist.hist(x, 40, histtype='stepfilled', orientation='vertical', color='gray')
x_hist.invert_yaxis()
y_hist.hist(y, 40, histtype='stepfilled', orientation='horizontal', color='gray')
y_hist.invert_xaxis()

在这里插入图片描述

二、Matplotlib绘图界面设置

2.1 坐标界限与标题

代码含义参数
plt.xlim()定义x轴坐标界限最左边的值,最右边的值
plt.ylim()定义y轴坐标界限最下边的值,最上边的值
plt.axis()设置坐标界限[xmin,xmax,ymin,ymax]
plt.axis('tight')收紧坐标轴,不留空白
plt.axis('equal')设置屏幕显示图形的分辨率(两轴单位长度比例)
plt.title()图形标题
plt.xlabel()x轴坐标标题
plt.ylabel()y轴坐标标题
plt.style.use()表格风格
ax.spines['top'].set_color('none')隐藏坐标轴顶边界
ax.spines['right'].set_color('none')隐藏坐标轴右边界
ax.xaxis.set_major_locator(MultipleLocator(2))定义x坐标轴的刻度单位from matplotlib.pyplot import MultipleLocator
ax.yaxis.set_major_locator(MultipleLocator(0.1))定义y坐标轴的刻度单位from matplotlib.pyplot import MultipleLocator
plt.xticks()更换刻度坐标位置,替代数据([0.2, 0.4, 0.6], ['A', 'B', 'C']

2.2 表格风格

使用plt.style.available可以看到所有的风格

Solarize_Light2_classic_test_patchbmhclassicdark_background
fastfivethirtyeightggplotgrayscaleseaborn
seaborn-brightseaborn-colorblindseaborn-darkseaborn-dark-paletteseaborn-darkgrid
seaborn-deepseaborn-mutedseaborn-notebookseaborn-paperseaborn-pastel
seaborn-posterseaborn-talkseaborn-ticksseaborn-whiteseaborn-whitegrid
tableau-colorblind10

样式表的使用方法

plt.style.use('fivethirtyeight')

这样会改变所有表格的风格,如果需要,可以使用风格上下文管理器临时更换至另一种风格:

with plt.style.context('fivethirtyeight'):
    plt.plot([1,2,3], [3,1,2])

dark_background风格

plt.style.use('dark_background')

x = np.linspace(0,10,1000)
fig, ax = plt.subplots()
ax.plot(x, np.sin(x),'-b')
ax.plot(x, np.cos(x), '--r')

在这里插入图片描述

2.3 文字与注释

plt.text():添加注释(等于ax.text())
该方法需要x轴位置、y轴位置、字符串、以及一些可选参数,如文字颜色、字号、风格、对齐方式等

plt.plot([1,2,3,4,5,6], [2,5,6,1,3,4])

# 在图中添加文字
ax.text(1,2,(1,2), ha='center')
ax.text(3,6,'(3, 6)', ha='right')
ax.text(4,1,str((4,1)))

在这里插入图片描述

transform参数:坐标变换与文字位置

ax.transData:以数据为基准的坐标变换(坐标轴)
ax.transAxes:以坐标轴为基准的坐标变换(以坐标轴维度为单位)(坐标系比例)
fig.transFigure:以图形为基准的坐标变换(以图形维度为单位)(图比例)

ax.set_xlim(0,10)
ax.set_ylim(0,10)

# 在图中添加文字
ax.text(1, 5, ". Data: (1, 5)", transform=ax.transData)
ax.text(0.5, 0.1, ". Axes: (0.5, 0.1)", transform=ax.transAxes)
ax.text(0.4, 0.4, ". Figure: (0.4, 0.4)", transform=fig.transFigure)

在这里插入图片描述
当改变坐标轴时,只有ax.transData的点会变

ax.set_xlim(-2,2)
ax.set_ylim(-6,6)

在这里插入图片描述

2.3.1 箭头与注释

plt.annotate():画箭头及注释

ax.set_xlim(-2,5)
ax.set_ylim(-6,6)

ax.annotate('A', xy=(3, 1), xytext=(4, 4), arrowprops=dict(facecolor='black', shrink=0.05))
ax.annotate('B', xy=(1, 1), xytext=(4, 3), arrowprops=dict(arrowstyle="->", connectionstyle="angle3,angleA=0,angleB=-90"))

在这里插入图片描述

ax.annotate('B', xy=(1, 1), bbox=dict(boxstyle="round",fc="none",ec="gray"), xytext=(4, 3),
            ha='center',arrowprops=dict(arrowstyle="->", connectionstyle="angle3,angleA=0,angleB=-90"))

在这里插入图片描述

2.3.2 自定义坐标刻度

定义坐标轴的刻度单位

ax.xaxis.set_major_locator(MultipleLocator(0.2))
ax.yaxis.set_major_locator(MultipleLocator(0.3))

在这里插入图片描述
隐藏上边界右边界

ax.spines['top'].set_color('none')
ax.spines['right'].set_color('none')

在这里插入图片描述
更换刻度

plt.xticks([0.2, 0.4, 0.6, 0.8], ['A', 'B', 'C', 'D'])

在这里插入图片描述

主要刻度与次要刻度

主要刻度往往更大,次要刻度往往更小,比如对数图

# 创建图形
fig = plt.figure()
# 坐标轴
ax = plt.axes(xscale='log', yscale='log')
ax.set_xlim(10**0,10**5)
ax.set_ylim(10**0,10**5)

在这里插入图片描述
设置每个坐标轴的formatterlocator自定义刻度属性

隐藏刻度与标签

隐藏刻度与标签通常使用plt.NullLocator()plt.NullFormatter()实现
下列我们除去了X轴标签(但是保留了刻度线/网格线),Y轴的刻度(标签也一并移除)

# 创建图形
fig = plt.figure()
# 坐标轴
ax = plt.axes()
ax.set_xlim(0,5)
ax.set_ylim(0, 5)

ax.yaxis.set_major_locator(plt.NullLocator())
ax.xaxis.set_major_formatter(plt.NullFormatter())

在这里插入图片描述

增减刻度数量

通过plt.MaxNLocator()设置最多显示多少刻度

fig, ax = plt.subplots(4, 4, sharex=True, sharey=True)
for axi in ax.flat:
    axi.xaxis.set_major_locator(plt.MaxNLocator(5))
    axi.yaxis.set_major_locator(plt.MaxNLocator(5))

在这里插入图片描述

2.3.3 格式生成器与定位器小结

定位器类描述
NullLocator无刻度
FixedLocator刻度位置固定
IndexLocator用索引作为定位器(如x=range(len(y))
LinearLocator从min到max均匀吩咐刻度
LogLocator从min到max按对数分布刻度
MultipleLocator刻度和范围都是基数(base)的倍数
MaxNLocator为最大刻度找到最优位置
AutoLocator(默认)以MaxNLocator进行简单配置
AutoMinorLocator次要刻度的定位器
格式生成器类描述
NullFormatter刻度上无标签
IndexFormatter将一组标签设置为字符串
FixedFormatter手动为刻度设置标签
FuncFormatter用自定义函数设置标签
FormatStrFormatter为每个刻度值设置字符串格式
ScalarFormatter(默认)为标签值设置标签
LogFormatter对数坐标轴的默认格式生成器

2.4 图线含义说明

函数参数含义
ax.legend()可以没有参数,也可以有以下参数创建图线含义
loc='upper left'图线说明位置
frameon=False取消图例外框
ncol=2图例标签列数
fancybox=True图例圆角边框
framealpha=0.5边框透明度
borderpad=1文字间距
shadow=True增加阴影

plt.legend():创建包含每个图形元素的图例

x = np.linspace(0,10,1000)
fig, ax = plt.subplots()
ax.plot(x, np.sin(x),'-b', label='Sin')
ax.plot(x, np.cos(x), '--r', label='Cos')

leg = ax.legend(loc='upper left', frameon=True, ncol=2, fancybox=True, framealpha=0.5, borderpad=1, shadow=True)

在这里插入图片描述

选择图例显示的元素

通过在plt.plot()里面使用或不使用label参数来确定是否显示图标

x = [1,2,3,4,5,6]
plt.plot(x, [2,5,6,4,2,3], label='1')
plt.plot(x, [3,4,1,6,2,5], label='2')
plt.plot(x, [5,8,4,6,2,9])
plt.plot(x, [2,4,5,8,1,6], label='4')
plt.plot(x, [9,6,4,2,8,3])

# 显示图标
plt.legend()

在这里插入图片描述

在图例中显示不同尺寸的点

la = np.random.uniform(0,10,100) # 横坐标
lo = np.random.uniform(0,10,100)  # 纵坐标
po = np.random.randint(0,100,100)  # 颜色
ar = np.random.randint(0,1000,100)  # 大小

# 画图
plt.scatter(lo, la, label=None, c=po, cmap='viridis', s=ar,linewidth=0, alpha=0.5)
# 画图例
for ar in [100,200,300]:
    plt.scatter([],[],c='k',alpha=0.3, s=ar,label=str(ar))


# 显示图标
plt.legend(scatterpoints=1, frameon=False, labelspacing=1)

在这里插入图片描述

2.5 配置颜色条

为颜色条添加标题

cd = plt.colorbar()
cb.set_label('label')

通过plt.colorbat函数创建颜色条

# 画图
x = np.linspace(0,10,1000)
I = np.sin(x)*np.cos(x[:,np.newaxis])

plt.imshow(I)
plt.colorbar()

在这里插入图片描述
配置颜色条

cmap参数:设置颜色条的配色方案

plt.imshow(I, cmap='gray')

在这里插入图片描述

顺序配色方案:一组连续的颜色构成的配色方案(例如binary或viridis)
互逆配色方案:由两种互补的颜色构成,表示两种含义(例如RdBu或PuOr)
定性配色方案:随机顺序的一组颜色(例如rainbow或jet)

plt.imshow(I,cmap='jet')

在这里插入图片描述

颜色条刻度的限制与扩展功能的设置

可以缩短颜色取值的上下限,对超出上下限的数据,通过extend参数用三角箭头表示比上限大或比上限小的数

x = np.linspace(0,10,1000)
I = np.sin(x)*np.cos(x[:,np.newaxis])
# 为图像设置1%噪点
speckles = (np.random.random(I.shape)<0.01)
I[speckles] = np.random.normal(0,3,np.count_nonzero(speckles))

plt.figure(figsize=(10,3.5))

plt.subplot(1,2,1)
plt.imshow(I, cmap='RdBu')
plt.colorbar()

plt.subplot(1,2,2)
plt.imshow(I, cmap='RdBu')
plt.colorbar(extend='both')
plt.clim(-1,1)

在这里插入图片描述
离散型颜色条
有时候需要表示离散的数据,可以使用plt.cm.get_cmap()参数

x = np.linspace(0,10,1000)
I = np.sin(x)*np.cos(x[:,np.newaxis])

plt.imshow(I, cmap=plt.cm.get_cmap('Blues', 6))
plt.colorbar()
plt.clim(-1,1)

在这里插入图片描述

2.6 手动配置图形

# 用灰色背景
ax = plt.axes(fc='#E6E6E6')
ax.set_axisbelow(True)

# 画上白色的网格线
plt.grid(color='w', linestyle='solid')

# 隐藏坐标轴的线条
for spine in ax.spines.values():
    spine.set_visible(False)

# 隐藏上边与右边的刻度
ax.xaxis.tick_bottom()
ax.yaxis.tick_left()

# 弱化刻度与标签
ax.tick_params(colors='gray', direction='out')
for tick in ax.get_xticklabels():
    tick.set_color('gray')
for tick in ax.get_yticklabels():
    tick.set_color('gray')

# 设置频次直方图轮廓设与填充色
ax.hist(x, edgecolor='#E6E6E6', color='#EE6666')

在这里插入图片描述

该方法配置起来很码麻烦,下面这种方法只需配置一次就可以用到所有图形上

2.7 修改默认配置

import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
from matplotlib import cycler

#fig, ax = plt.subplots()

# 先复制目前rcParams字典,修改够可以还原回来
Ipython_default = plt.rcParams.copy()

# 用plt.rc函数修改配置参数
colors = cycler('color', ['#EE6666', '#3388BB', '#9988DD', '#EECC55', '#88BB44', '#FFBBBB'])
plt.rc('axes', facecolor='#E6E6E6', edgecolor='none', axisbelow=True, grid=True, prop_cycle=colors)
plt.rc('grid', color='w', linestyle='solid')
plt.rc('xtick', direction='out', color='gray')
plt.rc('ytick', direction='out', color='gray')
plt.rc('patch', edgecolor='#E6E6E6')
plt.rc('lines', linewidth=2)

x = np.random.randn(1000)
plt.hist(x)

# 显示图片
plt.show()

在这里插入图片描述
画一些线图看看rc参数的效果

import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
from matplotlib import cycler

#fig, ax = plt.subplots()

# 先复制目前rcParams字典,修改够可以还原回来
Ipython_default = plt.rcParams.copy()

# 用plt.rc函数修改配置参数
colors = cycler('color', ['#EE6666', '#3388BB', '#9988DD', '#EECC55', '#88BB44', '#FFBBBB'])
plt.rc('axes', facecolor='#E6E6E6', edgecolor='none', axisbelow=True, grid=True, prop_cycle=colors)
plt.rc('grid', color='w', linestyle='solid')
plt.rc('xtick', direction='out', color='gray')
plt.rc('ytick', direction='out', color='gray')
plt.rc('patch', edgecolor='#E6E6E6')
plt.rc('lines', linewidth=2)

for i in range(4):
    plt.plot(np.random.rand(10))

# 显示图片
plt.show()

在这里插入图片描述

Matplotlib文档里面还有更多信息

2.8 可视化异常处理

某数据公认范围是70±5,我测出来却是75±10,我的数据是否与公认值一致
在图形可视化的结果中用图形将误差显示出来,可以提供充分的信息

基本误差线(errorbar)

fmt参数:控制线条和点的外观

x = np.linspace(0,10,50)
dy = 0.8
y = np.sin(x)+dy*np.random.randn(50)

plt.errorbar(x,y,yerr=dy,fmt='.k')

在这里插入图片描述

errorbar可以定义误差线图形的风格

x = np.linspace(0,10,50)
dy = 0.8
y = np.sin(x)+dy*np.random.randn(50)

plt.errorbar(x,y,yerr=dy,fmt='o',color='black',ecolor='lightgray',elinewidth=3,capsize=0)

在这里插入图片描述

还可以设置水平方向的误差(xerr)、单侧误差(one-sidederrorbar)、以及其他形式的误差

三、用Matplotlib画三维图

画三维图需要mplot3d模块,在创建任意一个普通坐标轴的过程中加入projection='3d'关键字,从而创建三维坐标轴

import matplotlib.pyplot as plt
from mpl_toolkits import mplot3d
import numpy as np

fig = plt.figure()
ax = plt.axes(projection='3d')

# 画图代码

# 显示图片
plt.show()

后序代码将这些代码省略了,将后面的代码套入画图代码里面即可
在这里插入图片描述

3.1 三维数据点与线

ax.plot3Dax.scatter3D来创建三维坐标的线图与散点图,三维函数的参数与二维函数的参数基本相同

# 三维线的数据
zline = np.linspace(0, 15, 1000)
xline = np.sin(zline)
yline = np.cos(zline)
ax.plot3D(xline, yline, zline, 'gray')

# 三维散点的数据
zdata = 15*np.random.random(100)
xdata = np.sin(zdata)+0.1*np.random.randn(100)
ydata = np.cos(zdata)+0.1*np.random.randn(100)
ax.scatter3D(xdata, ydata, zdata, c=zdata, cmap='Greens')

在这里插入图片描述
默认情况,散点会自动改变透明度,以在平面上呈现出立体感

3.2 三维等高线图

ax.contour3D要求所有数据都是二维网格数据的格式,由函数计算z轴数值

def f(x, y):
    return np.sin(np.sqrt(x**2 + y**2))

x = np.linspace(-6, 6, 30)
y = np.linspace(-6, 6, 30)

X, Y = np.meshgrid(x, y)
Z = f(X, Y)

ax.contour3D(X, Y, Z, 50, cmap='binary')
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_zlabel('z')

在这里插入图片描述
view_init可以调整观察角度和方位角,在这个例子中,将俯仰角调整为60度,方位角调整为35度,在上面的代码基础上加上下面这行代码:

ax.view_init(60, 35)

在这里插入图片描述
也可以在图中点击拖拽图形装换角度

3.3 线框图和曲面图

ax.plot_wireframe绘制线框图

def f(x, y):
    return np.sin(np.sqrt(x**2 + y**2))

x = np.linspace(-6, 6, 30)
y = np.linspace(-6, 6, 30)

X, Y = np.meshgrid(x, y)
Z = f(X, Y)

ax.plot_wireframe(X, Y, Z, color='black')
ax.set_title('wireframe')

在这里插入图片描述
ax.plot_surface绘制曲面图

def f(x, y):
    return np.sin(np.sqrt(x**2 + y**2))

x = np.linspace(-6, 6, 30)
y = np.linspace(-6, 6, 30)

X, Y = np.meshgrid(x, y)
Z = f(X, Y)

ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap='viridis', edgecolor='none')
ax.set_title('surface')

在这里插入图片描述
画曲面图的二维数据可以是直角坐标系数据,也可以是极坐标数据,下面是极坐标数据创建的图

def f(x, y):
    return np.sin(np.sqrt(x**2 + y**2))

r = np.linspace(0, 6, 20)
theta = np.linspace(-0.9*np.pi, 0.8*np.pi, 40)
r, theta = np.meshgrid(r, theta)

X = r * np.sin(theta)
Y = r * np.cos(theta)
Z = f(X, Y)

ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap='viridis', edgecolor='none')

在这里插入图片描述

3.4 曲面三角剖分

上面哪些要求均匀采样的网格数据显得太过严谨,不容易实现,如果没有笛卡尔或极坐标网格的均匀绘图,可以使用三角剖分图形

ax.scatter绘制三维采样的曲面图

def f(x, y):
    return np.sin(np.sqrt(x**2 + y**2))

r = 6*np.random.random(1000)
theta = 2*np.pi*np.random.random(1000)

X = np.ravel(r * np.sin(theta))
Y = np.ravel(r * np.cos(theta))
Z = f(X, Y)

ax.scatter(X, Y, Z, c=Z, cmap='viridis', linewidth=0.5)

在这里插入图片描述
这图还有很多地方需要修补,可以由ax.plot_trisurf函数来完成,它首先找到一组所有点都连接起来的三角形,然后用这三角形创建曲面

def f(x, y):
    return np.sin(np.sqrt(x**2 + y**2))

r = 6*np.random.random(1000)
theta = 2*np.pi*np.random.random(1000)

X = np.ravel(r * np.sin(theta))
Y = np.ravel(r * np.cos(theta))
Z = f(X, Y)

ax.plot_trisurf(X, Y, Z, cmap='viridis', edgecolor='none')

在这里插入图片描述
可以用该方法画莫比乌斯带

theta = np.linspace(0, 2*np.pi, 30)
w = np.linspace(-0.25, 0.25, 8)
w, theta = np.meshgrid(w, theta)

phi = 0.5*theta

# x-y平面内的半径
r = 1+w*np.cos(phi)

x = np.ravel(r*np.cos(theta))
y = np.ravel(r*np.sin(theta))
z = np.ravel(w*np.sin(phi))

# 用基本参数化方法定义三角剖分
from matplotlib.tri import Triangulation
tri = Triangulation(np.ravel(w), np.ravel(theta))

ax.plot_trisurf(x, y, z, triangles=tri.triangles, cmap='viridis', linewidths=0.2)

ax.set_xlim(-1,1)
ax.set_ylim(-1,1)
ax.set_zlim(-1,1)

在这里插入图片描述

四、用Seaborn做数据可视化

4.1 Seaborn与Matplotlib

Matplotlib画图

import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np

plt.figure()

x = np.linspace(0, 10, 500)
y = np.cumsum(np.random.randn(500, 6), 0)

plt.plot(x, y)
plt.legend('ABCDEF', ncol=2, loc='upper left')

# 显示图片
plt.show()

在这里插入图片描述

Seaborn有许多高级的画图功能,而且可以改写Matplotlib的默认参数,从而用简单的Matplotlib获得更好的效果,可以用Seabornset()方法设置样式
其他代码和上面的一样,只是添加导入这个模块和使用set()函数

import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
import seaborn as sns

sns.set()
plt.figure()

x = np.linspace(0, 10, 500)
y = np.cumsum(np.random.randn(500, 6), 0)

plt.plot(x, y)
plt.legend('ABCDEF', ncol=2, loc='upper left')

# 显示图片
plt.show()

在这里插入图片描述

4.2 Seaborn图形介绍

很多图形用Matplotlib都可以实现,三用Seaborn会更方便

频次直方图、KDE和密度图
频次直方图

import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
import seaborn as sns
import pandas as pd

sns.set()
plt.figure()

data = np.random.multivariate_normal([0, 0], [[5, 2], [2, 2]], size=2000)
data = pd.DataFrame(data, columns=['x', 'y'])

for col in 'xy':
    plt.hist(data[col], alpha=0.5)

# 显示图片
plt.show()

在这里插入图片描述
用KDE获取变量分布的平滑评估,通过sns.kdeplot实现

for col in 'xy':
    sns.kdeplot(data[col], shade=True)

在这里插入图片描述

distplot可以让频次直方图与KDE结合起来

for col in 'xy':
    sns.distplot(data[col])

在这里插入图片描述
如果想kdeplot输入的是二维数据集,那么可以获得一个二维数可视化

sns.kdeplot(data['x'],data['y'])

在这里插入图片描述
用sns.jointplot可以同时看到两个变量的联合分布与单变量的独立分布,在这里使用白色背景

with sns.axes_style('white'):
    sns.jointplot("x", "y", data, kind='kde')

在这里插入图片描述

with sns.axes_style('white'):
    sns.jointplot("x", "y", data, kind='hex')

在这里插入图片描述
矩阵图
下面是四个变量之间关系的矩阵图

import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
import seaborn as sns
import pandas as pd

sns.set()
plt.figure()

iris = sns.load_dataset("iris")
print(iris.head())
'''
   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
'''
sns.pairplot(iris, hue='species', size=2.5)

# 显示图片
plt.show()

在这里插入图片描述
分面频次直方图

import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
import seaborn as sns
import pandas as pd

sns.set()
plt.figure()

tips = sns.load_dataset("tips")
print(tips)
'''
     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
..          ...   ...     ...    ...   ...     ...   ...
239       29.03  5.92    Male     No   Sat  Dinner     3
240       27.18  2.00  Female    Yes   Sat  Dinner     2
241       22.67  2.00    Male    Yes   Sat  Dinner     2
242       17.82  1.75    Male     No   Sat  Dinner     2
243       18.78  3.00  Female     No  Thur  Dinner     2

[244 rows x 7 columns]
'''
tips['tip_pct'] = 100*tips['tip']/tips['total_bill']
grid = sns.FacetGrid(tips, row="sex", col="time", margin_titles=True)
grid.map(plt.hist, "tip_pct", bins=np.linspace(1, 40, 15))

# 显示图片
plt.show()

在这里插入图片描述
因子图

import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
import seaborn as sns
import pandas as pd

sns.set()
plt.figure()

tips = sns.load_dataset("tips")
tips['tip_pct'] = 100*tips['tip']/tips['total_bill']

with sns.axes_style(style='ticks'):
    g = sns.factorplot("day", "total_bill", "sex", data=tips, kind="box")
    g.set_axis_labels("day", "Total Bill")

# 显示图片
plt.show()

在这里插入图片描述
联合分布

with sns.axes_style('white'):
    sns.jointplot("total_bill", "tip", data=tips, kind='hex')

在这里插入图片描述

with sns.axes_style('white'):
    sns.jointplot("total_bill", "tip", data=tips, kind='reg')

在这里插入图片描述
条形图sns.factorplot画条形图

import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
import seaborn as sns
import pandas as pd

sns.set()
plt.figure()

planets = sns.load_dataset('planets')
print(planets.head())
'''
            method  number  orbital_period   mass  distance  year
0  Radial Velocity       1         269.300   7.10     77.40  2006
1  Radial Velocity       1         874.774   2.21     56.95  2008
2  Radial Velocity       1         763.000   2.60     19.84  2011
3  Radial Velocity       1         326.030  19.40    110.62  2007
4  Radial Velocity       1         516.220  10.50    119.47  2009
'''
with sns.axes_style('white'):
    g = sns.factorplot("year", data=planets, aspect=2, kind="count", color='steelblue')
    g.set_xticklabels(step=5)

# 显示图片
plt.show()

在这里插入图片描述

with sns.axes_style('white'):
    g = sns.factorplot("year", data=planets, aspect=4.0, kind="count", hue='method', order=range(2001, 2015))
    g.set_ylabels('Number of Planets Discovered')

在这里插入图片描述

  • 36
    点赞
  • 253
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值