在 python 中使用 matplotlib 创建 3D 曲面图
Creating a 3D surface plot with matplotlib in python
我正在尝试绘制 3D 表面,但我遇到了一些麻烦,因为 matplotlib
的文档似乎不是很详尽并且缺少示例。无论如何,我编写的程序是通过有限差分法数值求解热方程。这是我的代码:
## This program is to implement a Finite Difference method approximation
## to solve the Heat Equation, u_t = k * u_xx,
## in 1D w/out sources & on a finite interval 0 < x < L. The PDE
## is subject to B.C: u(0,t) = u(L,t) = 0,
## and the I.C: u(x,0) = f(x).
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import cm
from mpl_toolkits.mplot3d import Axes3D
# Parameters
L = 1 # length of the rod
T = 10 # terminal time
N = 40 # spatial values
M = 1600 # time values/hops; (M ~ N^2)
s = 0.25 # s := k * ( (dt) / (dx)^2 )
# uniform mesh
x_init = 0
x_end = L
dx = float(x_end - x_init) / N
x = np.arange(x_init, x_end, dx)
x[0] = x_init
# time discretization
t_init = 0
t_end = T
dt = float(t_end - t_init) / M
t = np.arange(t_init, t_end, dt)
t[0] = t_init
# time-vector
for m in xrange(0, M):
t[m] = m * dt
# spatial-vector
for j in xrange(0, N):
x[j] = j * dx
# definition of the solution u(x,t) to u_t = k * u_xx
u = np.zeros((N, M+1)) # array to store values of the solution
# Finite Difference Scheme:
u[:,0] = x * (x - 1) #initial condition
for m in xrange(0, M):
for j in xrange(1, N-1):
if j == 1:
u[j-1,m] = 0 # Boundary condition
elif j == N-1:
u[j+1,m] = 0 # Boundary Condition
else:
u[j,m+1] = u[j,m] + s * ( u[j+1,m] -
2 * u[j,m] + u[j-1,m] )
这是我为尝试绘制 3D 曲面图而编写的内容:
# for 3D graph
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
surf = ax.plot_surface(x, t, u, rstride=1, cstride=1, cmap=cm.coolwarm, linewidth=0, antialiased=False)
fig.colorbar(surf, shrink=0.5, aspect=5)
plt.show()
当我 运行 绘制图表的代码时出现此错误:"ValueError: shape mismatch: two or more arrays have incompatible dimensions on axis 1."
非常感谢您的帮助。我认为出现错误是因为我将 u
定义为 Nx(M+1)
矩阵,但有必要使原始程序 运行。我不确定如何更正此问题以便正确绘制图表。谢谢!
使用这段代码(看评论):
# plot 3d surface
# create a meshgrid of (x,t) points
# T and X are 2-d arrays
T, X = np.meshgrid(t,x)
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
# Use X and T arrays to plot u
# shape of X, T and u must to be the same
# but shape of u is [40,1601] and I will skip last row while plotting
surf = ax.plot_surface(X, T, u[:,:1600], rstride=1, cstride=1, cmap=cm.coolwarm, linewidth=0, antialiased=False)
fig.colorbar(surf, shrink=0.5, aspect=5)
plt.show()
结果:
because the documentation for matplotlib does not appear to be very thorough and is lacking in examples
打印出变量 x
、t
和 u
的形状很有帮助:
x.shape == (40,)
t.shape == (1600,)
u.shape == (40, 1601)
所以这里有两个问题。
第一个是 x
和 t
是一维的,即使它们需要是二维的。
而第二个是u
在二维中比t
多了一个元素。
您可以通过 运行
来解决这两个问题
t, x = np.meshgrid(t, x)
u = u[:,:-1]
在创建 3d 图之前。
我正在尝试绘制 3D 表面,但我遇到了一些麻烦,因为 matplotlib
的文档似乎不是很详尽并且缺少示例。无论如何,我编写的程序是通过有限差分法数值求解热方程。这是我的代码:
## This program is to implement a Finite Difference method approximation
## to solve the Heat Equation, u_t = k * u_xx,
## in 1D w/out sources & on a finite interval 0 < x < L. The PDE
## is subject to B.C: u(0,t) = u(L,t) = 0,
## and the I.C: u(x,0) = f(x).
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import cm
from mpl_toolkits.mplot3d import Axes3D
# Parameters
L = 1 # length of the rod
T = 10 # terminal time
N = 40 # spatial values
M = 1600 # time values/hops; (M ~ N^2)
s = 0.25 # s := k * ( (dt) / (dx)^2 )
# uniform mesh
x_init = 0
x_end = L
dx = float(x_end - x_init) / N
x = np.arange(x_init, x_end, dx)
x[0] = x_init
# time discretization
t_init = 0
t_end = T
dt = float(t_end - t_init) / M
t = np.arange(t_init, t_end, dt)
t[0] = t_init
# time-vector
for m in xrange(0, M):
t[m] = m * dt
# spatial-vector
for j in xrange(0, N):
x[j] = j * dx
# definition of the solution u(x,t) to u_t = k * u_xx
u = np.zeros((N, M+1)) # array to store values of the solution
# Finite Difference Scheme:
u[:,0] = x * (x - 1) #initial condition
for m in xrange(0, M):
for j in xrange(1, N-1):
if j == 1:
u[j-1,m] = 0 # Boundary condition
elif j == N-1:
u[j+1,m] = 0 # Boundary Condition
else:
u[j,m+1] = u[j,m] + s * ( u[j+1,m] -
2 * u[j,m] + u[j-1,m] )
这是我为尝试绘制 3D 曲面图而编写的内容:
# for 3D graph
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
surf = ax.plot_surface(x, t, u, rstride=1, cstride=1, cmap=cm.coolwarm, linewidth=0, antialiased=False)
fig.colorbar(surf, shrink=0.5, aspect=5)
plt.show()
当我 运行 绘制图表的代码时出现此错误:"ValueError: shape mismatch: two or more arrays have incompatible dimensions on axis 1."
非常感谢您的帮助。我认为出现错误是因为我将 u
定义为 Nx(M+1)
矩阵,但有必要使原始程序 运行。我不确定如何更正此问题以便正确绘制图表。谢谢!
使用这段代码(看评论):
# plot 3d surface
# create a meshgrid of (x,t) points
# T and X are 2-d arrays
T, X = np.meshgrid(t,x)
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
# Use X and T arrays to plot u
# shape of X, T and u must to be the same
# but shape of u is [40,1601] and I will skip last row while plotting
surf = ax.plot_surface(X, T, u[:,:1600], rstride=1, cstride=1, cmap=cm.coolwarm, linewidth=0, antialiased=False)
fig.colorbar(surf, shrink=0.5, aspect=5)
plt.show()
结果:
because the documentation for matplotlib does not appear to be very thorough and is lacking in examples
打印出变量 x
、t
和 u
的形状很有帮助:
x.shape == (40,)
t.shape == (1600,)
u.shape == (40, 1601)
所以这里有两个问题。
第一个是 x
和 t
是一维的,即使它们需要是二维的。
而第二个是u
在二维中比t
多了一个元素。
您可以通过 运行
t, x = np.meshgrid(t, x)
u = u[:,:-1]
在创建 3d 图之前。