在数据可视化实践过程中经常需要对三维甚至更高纬度数据进行可视化。由于视线阻挡,人们在看三维物体时并不能观测清楚完全。有时候需要获取三维图形的某个截面来单独分析数据。
# -*- coding: utf-8 -*-
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
import matplotlib as mpl
from scipy import interpolate
import matplotlib.cm as cm
import matplotlib.pyplot as plt
xmin=-10
ymin=-10
xmax=10
ymax=10
rawStrideNum=50#原始数据x,y的分段数
InterpolationNum=100#使用插值方法获取某个截面数据 获取数据时将数据分割的分段数
#生成原始数据的f value
def fm((x, y)):
return (np.sin(x) + 0.05 * x ** 2+ np.sin(y) + 0.05 * y ** 2)
#原始数据获取
x = np.linspace(xmin, xmax, rawStrideNum)
y = np.linspace(ymin,ymax,rawStrideNum)
X, Y = np.meshgrid(x, y)#50*50的网格数据
Z = fm((X, Y))
#开始作图
fig = plt.figure(figsize=(9, 6))
#Draw sub-graph1
ax=plt.subplot(1, 2, 1,projection = '3d')
surf = ax.plot_surface(X, Y, Z, rstride=2, cstride=2, cmap=cm.coolwarm,linewidth=0.5, antialiased=True)
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_zlabel('f(x, y)')
plt.colorbar(surf, shrink=0.5, aspect=5)#标注
#subplot2data preparation
#(1)用插值函数拟合数据
newfun=interpolate.interp2d(X, Y, Z,kind="cubic")#返回的是一个函数 newfun为一个函数
xnew = np.linspace(xmin, xmax, InterpolationNum)#重新划分x,y间隔数为InterpolationNum个
ynew = np.linspace(ymin, ymax, InterpolationNum)
fnew=newfun(xnew,ynew)#得到重新划分x,y间隔后fnew值 fnew为InterpolationNum*InterpolationNum的二维数组
def getXCrossSectionData(f,xval):
index=(xval-xmin)*1.0/(xmax-xmin)*InterpolationNum
print " x index ",int(index)
FixedX=np.empty(InterpolationNum)
FixedX.fill(xval)
return FixedX,f[int(index)]
def getYCrossSectionData(f,yval):
index2=(yval-ymin)*1.0/(ymax-ymin)*InterpolationNum
print "y index",int(index2)
FixedY=np.empty(InterpolationNum)
FixedY.fill(yval)
return FixedY,f[:,int(index2)]
FixedX,Z_FixedX=getXCrossSectionData(fnew,-9)#设置想要获取的x截面
FixedY,Z_FixedY=getYCrossSectionData(fnew,5)
#在原图上添加直线,从吻合性判断数据的准确性
ax.plot(FixedX, ynew, Z_FixedX)
ax.plot(xnew, FixedY, Z_FixedY)
#Draw sub-graph2单独抽取某个截面
ax2=plt.subplot(122, projection = '3d')
ax2.plot(FixedX, ynew, Z_FixedX)
ax2.plot(xnew, FixedY, Z_FixedY)
plt.show()