《Python数据分析实战》

1.高级图表

除去条状图、饼图等较为传统的图表,我们还可能需要用到其他形式的图表。

等值线图:

等值线图或等高线图在科学界很常用。这种可视化方法用一圈圈封闭的曲线组成的等值线图表示三维结构的表面,其中封闭的曲线表示的是一个个处于同一层次或z值相同的数据点。

import matplotlib.pyplot as plt
import numpy as np

dx=0.01 ; dy=0.01
x = np.arange(-2.0,2.0,dx)
y = np.arange(-2.0,2.0,dy)

#将原始数据变成网格
X,Y = np.meshgrid(x,y)

#定义等高线高度函数
def f(x,y):
    return (1 - y**5 + x**5)*np.exp(-x**2-y**2)

#填充颜色,colors填充的是等高线的线的颜色
C = plt.contour(X,Y,f(X,Y),8,colors='green')
#绘制等高线
plt.contourf(X,Y,f(X,Y),8,cmap=plt.cm.hot)
#显示各等高线的数据标签
plt.clabel(C,inline=1,fontsize=10)

#添加颜色图例
plt.colorbar()

#去除坐标轴
plt.xticks()
plt.yticks()

plt.show()

设置cmap前:

python 绘制 土 剖面 python绘制剖面图_3D

设置cmap后:

python 绘制 土 剖面 python绘制剖面图_3d_02

极区图:

这种图表由一系列呈放射状延伸的区域组成,其中每块区域占据一定的角度。因此若要用极区图表示两个不同的数值,分别指定它们在极区图中所占的分量:每块区域的半径r和它所占的角度,其实这就是极坐标(r,θ),是在坐标轴系中表示数据的另一种方法。

从图表的角度来看,你可以将其视作兼有饼图和条状图特点的图表。之所以说它像饼图,是因为每个区域的角度所表示的是其所属类别占全部类别的比例。至于说它像条状图,是因为半径的长度表示某一类别的数值大小。(也就是角度的大小代表某一类所占的比例,半径的长度代表某一类含有的数量)。

#极区图

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

N = 8

# 角度 0-2π N份
theta = np.arange(0.0,2*np.pi,2*np.pi / N)
# 半径 8份对应的半径长度
radii = np.array([4,7,5,3,1,5,6,7])

plt.axes([0.025,0.025,0.95,0.95],polar=True)

colors = np.array(['#4bb2c5','#c5b47f','#EAA228','#579575','#839557','#958c12','#953579','#4b5de4'])

bars = plt.bar(theta,radii,width=(2*np.pi/N),bottom=0.0,color=colors)

plt.show()

python 绘制 土 剖面 python绘制剖面图_子图_03

2.mplot3d

mplot3d工具集是matplotlib内置的标配,可用来实现3D数据可视化功能。

mplot3d仍然使用figure对象,只不过Axes对象要替换为该工具集的Axes3D对象。因此,使用Axes3D对象前,需先将其导入进来。

from mpl_toolkits.mplot3d import Axes3D

3D曲面:

计算出分割线坐标后,就可以用plot_surface()函数绘制曲面。蓝色三维曲面图表请见下图。

# 3D曲面

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

fig = plt.figure()
ax = Axes3D(fig)

X = np.arange(-2,2,0.1)
Y = np.arange(-2,2,0.1)
#把原始数据变成网格
X,Y = np.meshgrid(X,Y)

def f(x,y):
    return (1-y**5 + x**5)*np.exp(-x**2-y**2)

ax.plot_surface(X,Y,f(X,Y),rstride=1,cstride=1)

plt.show()

python 绘制 土 剖面 python绘制剖面图_python 绘制 土 剖面_04

修改颜色表,3D表面效果会更加突出,例如,可以用cmap参数指定各颜色。还可以用view_init()函数旋转曲面,修改elve和azim两个关键字参数,从不同的视角查看曲面,其中第一个关键字参数指定从哪个高度查看曲面,第二个参数指定曲面旋转的角度。

# 3D曲面

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

fig = plt.figure()
ax = Axes3D(fig)

X = np.arange(-2,2,0.1)
Y = np.arange(-2,2,0.1)
#把原始数据变成网格
X,Y = np.meshgrid(X,Y)

def f(x,y):
    return (1-y**5 + x**5)*np.exp(-x**2-y**2)

ax.plot_surface(X,Y,f(X,Y),rstride=1,cstride=1,cmap=plt.cm.hot)
ax.view_init(elev=30,azim=125)

plt.show()

python 绘制 土 剖面 python绘制剖面图_3d_05

3D散点图:

在所有3D图形中,散点图最常用。通过这种可视化方法,能够识别数据点的分布是否遵循某种特定趋势,尤其是可以识别它们是否有聚集成簇的趋势。

下面这个例子中,我们仍旧使用scatter()函数,使用方法跟绘制2D图形相同,但是要将其应用于Axes3D对象。这样做,你可以多次调用scatter()函数,在同一个3D对象中显示不同的序列。

#3D散点图

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

xs = np.random.randint(30,40,100)
ys = np.random.randint(20,30,100)
zs = np.random.randint(10,20,100)

xs2 = np.random.randint(50,60,100)
ys2 = np.random.randint(30,40,100)
zs2 = np.random.randint(50,70,100)

xs3 = np.random.randint(10,30,100)
ys3 = np.random.randint(40,50,100)
zs3 = np.random.randint(40,50,100)

fig = plt.figure()
ax = Axes3D(fig)

ax.scatter(xs,ys,zs)
ax.scatter(xs2,ys2,zs2,c='r',marker='^')
ax.scatter(xs3,ys3,zs3,c='g',marker='*')

ax.set_xlabel("X Label")
ax.set_ylabel("Y Label")
ax.set_zlabel("Z Label")

plt.show()

python 绘制 土 剖面 python绘制剖面图_子图_06

3D条状图:

数据分析常用的另一种3D图形是3D条状图。要绘制这种图表,同样是将bar()函数应用于Axes3D对象。如果定义了多个序列,可以在同一个3D对象上多次调用bar()函数。

#3D条状图

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

x = np.arange(8)
y = np.random.randint(0,10,8)
y2 = y + np.random.randint(0,3,8)
y3 = y2 + np.random.randint(0,3,8)
y4 = y3 + np.random.randint(0,3,8)
y5 = y4 + np.random.randint(0,3,8)

clr = ['#4bb2c5','#c5b47f','#EAA228','#579575','#839557','#958c12','#953579','#4b5de4']

fig = plt.figure()
ax = Axes3D(fig)

#zdir决定哪个坐标轴作为维度
ax.bar(x,y,0,zdir='y',color=clr)
ax.bar(x,y2,10,zdir='y',color=clr)
ax.bar(x,y3,20,zdir='y',color=clr)
ax.bar(x,y4,30,zdir='y',color=clr)
ax.bar(x,y5,40,zdir='y',color=clr)

ax.set_xlabel('X Axis')
ax.set_ylabel('Y Axis')
ax.set_zlabel('Z Axis')

ax.view_init(elev=40)

plt.show()

zdir设置为y时图像:

python 绘制 土 剖面 python绘制剖面图_3d_07

zdir设置为x时图像:

python 绘制 土 剖面 python绘制剖面图_python 绘制 土 剖面_08

3.多面板图形

在其他子图中显示子图:

我们现在来介绍一种更为高级的方法:把图表放入框架,在其他图表中显示。既然我们在讲框架,也就是Axes对象,你需要把Axes对象(也就是主图表)跟放置另一个Axes对象实例的框架分开。用figure()函数取到Figure对象,用add_axes()函数在它上面定义两个Axes对象。结国如下图。

#在其他子图中显示子图

import matplotlib.pyplot as plt
fig = plt.figure()

ax = fig.add_axes([0.1,0.1,0.8,0.8])
inner_ax = fig.add_axes([0.6,0.6,0.25,0.25])

plt.show()

python 绘制 土 剖面 python绘制剖面图_3D_09

附注:

  • 无论使用何种方法创建,每一个axes都是一个独立的图层
  • 每个图层除了绘图区以外都是透明的
  • 图层之间相互独立互不影响
  • 当两个axes绘图区之间有重叠的时候,创建命令在前的axes图层位置更靠近底层
  • axes.set_zorder()方法可改变当前图层层次高度,参数值越小位置越靠近底层
axes = figure.add_axes([left,bottom,width,height])

left:绘图区左侧边缘线与Figure画布左侧边缘线的距离

bottom:绘图区底部边缘线与Figure画布底部边缘线的距离

width:绘图区的宽度

height:绘图区的高度

它们的单位也不是传统的厘米、毫米这样的长度距离单位,而是Figure画布的百分比,因此它们的取值范围在[0,1]区间内,其中left与width的单位为Figure画布宽度的百分比,bottom与height的单位为Figure画布高度的百分比。

python 绘制 土 剖面 python绘制剖面图_子图_10

附注:pyplot.subplots()创建Axes绘图区。

fig, axes = pyplot.subplots(行数,列数)

创建区域位置参数及间隔参数可通过fig.subplots_adjust(left,right,top,bottom,wspace,hspace)方法改变。

fig, axes = plt.subplots(nrows=3,ncols=1)
fig.subplots_adjust(left=0.1,right=0.95,top=0.9,bottom=0.1,hspace=0.3)
axes[0].set_facecolor('skyblue')
axes[1].set_facecolor('lightskyblue')
axes[2].set_facecolor('deepskyblue')

plt.show()

python 绘制 土 剖面 python绘制剖面图_3D_11

left、right、bottom、top位置参考:

python 绘制 土 剖面 python绘制剖面图_3D_12

附注:figure.add_subplot()创建Axes绘图区

figure.add_subplot()方法与pyplot.subplots()方法一样,首先在Figure画布上划定出一块区域,然后按行和列进行布局,与pyplot.subplots()方法不同的是该方法一行命令只能创建一个Axes绘图区,即序号参数所指定的那个位置的Axes。

fig = plt.figure()

axes1 = fig.add_subplot(221)
axes1.set_facecolor('skyblue')
axes2 = fig.add_subplot(222)
axes2.set_facecolor('lightskyblue')
axes3 = fig.add_subplot(212)
axes3.set_facecolor('deepskyblue')

plt.show()

python 绘制 土 剖面 python绘制剖面图_3d_13

总结:绘图布局的创建主要有三种方法:

  1. axes = figure.add_axes([left,bottom,width,height])
  2. fig,axes = pyplot.subplots(行数,列数)
  3. axes = figure.add_subplot(行数,列数,序号)

详细信息可以参考:http://baijiahao.baidu.com/s?id=1575393755013387&wfr=spider&for=pc

为了更好地理解这种图形模式,你可以为Axes对象地plot()方法传入两列数据,所实现地效果见下图。

#在其他子图中显示子图

import matplotlib.pyplot as plt
import numpy as np

fig = plt.figure()

ax = fig.add_axes([0.1,0.1,0.8,0.8])
inner_ax = fig.add_axes([0.6,0.6,0.25,0.25])

x1 = np.arange(10)
y1 = np.array([1,2,7,1,5,2,4,2,3,1])
x2 = np.arange(10)
y2 = np.array([1,3,4,5,4,5,2,6,4,3])

ax.plot(x1,y1)
inner_ax.plot(x2,y2)

plt.show()

python 绘制 土 剖面 python绘制剖面图_3D_14

子图网格:

前面已讲过如何生成子图。而把图形分成多个区域,添加多个子图,可以用subplots()函数,方法也很简单。matplotlib的GridSpec()函数可用来管理更为复杂的情况。它把绘图区域分成多个子区域,你可以把一个或多个子区域分配给每一幅子图,效果如下图所示,其中每幅子图的大小、方位各不相同。

#子图网格

import matplotlib.pyplot as plt
import numpy as np

gs = plt.GridSpec(3,3)
fig = plt.figure(figsize=(6,6))

fig.add_subplot(gs[1,:2])

s2 = fig.add_subplot(gs[0,:2])
x = np.arange(10)
y = np.array([1,4,3,2,5,9,7,8,10,6])
s2.plot(x,y,'r')

fig.add_subplot(gs[2,0])
fig.add_subplot(gs[:2,2])

fig.add_subplot(gs[2,1:])

plt.show()

python 绘制 土 剖面 python绘制剖面图_3D_15

Matplotlib可以绘制更多的图像,可以参考:https://matplotlib.org/gallery/index.html#