将 2D 图扩展到 3D
Extend a 2D plot to 3D
我正在尝试在 3D 上显示我的 2D 数据 space。
下面是我的代码:
import numpy as np
import matplotlib.pyplot as plt
i = 60
n = 1000
r = 3.8
eps = 0.7
y = np.ones((n, i))
# random numbers on the first row of array x
np.random.seed(1)
x = np.ones((n+1, i))
x[0, :] = np.random.random(i)
def logistic(r, x):
return r * x * (1 - x)
present_indi = np.arange(i)
next_indi = (present_indi + 1) % i
prev_indi = (present_indi - 1) % i
for n in range(1000):
y[n, :] = logistic(r, x[n, :])
x[n+1, :] = (1-eps)*y[n, present_indi] + 0.5*eps*(y[n, prev_indi] + y[n, next_indi])
#print(x)
# the above logic generates a 2D array 'x'. with i columns and n rows.
fig, ax = plt.subplots()
for i in range(60):
for n in range(1000):
if n>=900:
ax.plot(i,x[n,i],'*k',ms=0.9)
plt.xlabel('i')
plt.ylabel('x')
plt.title('test')
plt.show()
以上代码完美显示了i和x图。我已经绘制了 X 的第一列的所有元素,然后是第二列的所有元素,然后是第三列等等......,使用嵌套的 for 循环逻辑(参考代码)
现在我需要做的是,将绘图扩展到 3D,即使用 Xaxis = i, Yaxis= n, Zaxis= array 'x'
我想绘制这样的东西:
我知道我必须使用 mplot3D
但是执行以下操作不会给我任何结果:
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
for i in range(60):
for n in range(1000):
if n>=900:
ax.plot_wireframe(i,n,x[n,i],rstride=1,cstride=1)
在 matplotlib
中绘制 3d 图像有点棘手。通常,您一次绘制整个表面而不是一次绘制一条线。为此,您传递三个二维数组,每个数组对应一个位置维度 (x, y, z)。但是你也不能只传递任何旧的二维数组;这些点本身必须按照精确的顺序排列!
有时您可以做一些有用的事情,但我发现使用 u
和 v
维度显式参数化图更容易。以下是我能够在这里工作的内容:
# Abstract u and v parameters describing surface coordinates
u_plt = np.arange(x.shape[1])
v_plt = np.arange(x.shape[0])
# The outer products here produce 2d arrays. We multiply by
# ones in this case for an identity transformation, but in
# general, you could use any broadcasted operation on `u`
# and `v`.
x_plt = np.outer(np.ones(np.size(v_plt)), u_plt)
y_plt = np.outer(v_plt, np.ones(np.size(u_plt)))
# In this case, our `x` array gives the `z` values directly.
z_plt = x
fig = plt.figure(figsize=(16, 10))
ax = fig.add_subplot(111, projection='3d')
ax.set_zmargin(1) # Add a bit more space around the plot.
ax.plot_wireframe(x_plt, y_plt, z_plt,
rstride=1, cstride=1, # "Resolution" of the plot
color='blue', linewidth=1.0,
alpha=0.7, antialiased=True)
# Tilt the view to match the example.
ax.view_init(elev = 45, azim = -45)
plt.xlabel('i')
plt.ylabel('x')
plt.title('test')
plt.show()
这是生成的图像。我不得不将 n
减少到 80 以使其完全可以理解,而且我不知道我在看什么,所以我不确定它是否正确。但我认为它看起来与您提供的示例大致相似。
为了说明这种方法的强大功能,这里有一个鹦鹉螺 shell。它使用两阶段参数化,可以压缩,但我发现它在概念上更清晰:
n_ticks = 100
# Abstract u and v parameters describing surface coordinates
u_plt = np.arange(n_ticks // 2) * 2
v_plt = np.arange(n_ticks)
# theta is the angle along the leading edge of the shell
# phi is the angle along the spiral of the shell
# r is the distance of the edge from the origin
theta_plt = np.pi * ((u_plt / n_ticks) * 0.99 + 0.005)
phi_plt = np.pi * v_plt / (n_ticks / 5)
r_plt = v_plt / (n_ticks / 5)
# These formulas are based on the formulas for rendering
# a sphere parameterized by theta and phi. The only difference
# is that r is variable here too.
x_plt = r_plt[:, None] * np.cos(phi_plt[:, None]) * np.sin(theta_plt[None, :])
y_plt = r_plt[:, None] * np.sin(phi_plt[:, None]) * np.sin(theta_plt[None, :])
z_plt = r_plt[:, None] * \
(np.ones(np.shape(phi_plt[:, None])) * np.cos(theta_plt[None, :]))
# This varies the color along phi
colors = cm.inferno(1 - (v_plt[:, None] / max(v_plt))) * \
np.ones(np.shape(u_plt[None, :, None]))
fig = plt.figure(figsize=(8, 8))
ax = fig.add_subplot(111, projection='3d')
ax.set_zmargin(1)
ax.plot_surface(x_plt, y_plt, z_plt,
rstride=1, cstride=1,
facecolors=colors, linewidth=1.0,
alpha=0.3, antialiased=True)
ax.view_init(elev = 45, azim = -45)
plt.show()
我正在尝试在 3D 上显示我的 2D 数据 space。
下面是我的代码:
import numpy as np
import matplotlib.pyplot as plt
i = 60
n = 1000
r = 3.8
eps = 0.7
y = np.ones((n, i))
# random numbers on the first row of array x
np.random.seed(1)
x = np.ones((n+1, i))
x[0, :] = np.random.random(i)
def logistic(r, x):
return r * x * (1 - x)
present_indi = np.arange(i)
next_indi = (present_indi + 1) % i
prev_indi = (present_indi - 1) % i
for n in range(1000):
y[n, :] = logistic(r, x[n, :])
x[n+1, :] = (1-eps)*y[n, present_indi] + 0.5*eps*(y[n, prev_indi] + y[n, next_indi])
#print(x)
# the above logic generates a 2D array 'x'. with i columns and n rows.
fig, ax = plt.subplots()
for i in range(60):
for n in range(1000):
if n>=900:
ax.plot(i,x[n,i],'*k',ms=0.9)
plt.xlabel('i')
plt.ylabel('x')
plt.title('test')
plt.show()
以上代码完美显示了i和x图。我已经绘制了 X 的第一列的所有元素,然后是第二列的所有元素,然后是第三列等等......,使用嵌套的 for 循环逻辑(参考代码)
现在我需要做的是,将绘图扩展到 3D,即使用 Xaxis = i, Yaxis= n, Zaxis= array 'x'
我想绘制这样的东西:
我知道我必须使用 mplot3D 但是执行以下操作不会给我任何结果:
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
for i in range(60):
for n in range(1000):
if n>=900:
ax.plot_wireframe(i,n,x[n,i],rstride=1,cstride=1)
在 matplotlib
中绘制 3d 图像有点棘手。通常,您一次绘制整个表面而不是一次绘制一条线。为此,您传递三个二维数组,每个数组对应一个位置维度 (x, y, z)。但是你也不能只传递任何旧的二维数组;这些点本身必须按照精确的顺序排列!
有时您可以做一些有用的事情,但我发现使用 u
和 v
维度显式参数化图更容易。以下是我能够在这里工作的内容:
# Abstract u and v parameters describing surface coordinates
u_plt = np.arange(x.shape[1])
v_plt = np.arange(x.shape[0])
# The outer products here produce 2d arrays. We multiply by
# ones in this case for an identity transformation, but in
# general, you could use any broadcasted operation on `u`
# and `v`.
x_plt = np.outer(np.ones(np.size(v_plt)), u_plt)
y_plt = np.outer(v_plt, np.ones(np.size(u_plt)))
# In this case, our `x` array gives the `z` values directly.
z_plt = x
fig = plt.figure(figsize=(16, 10))
ax = fig.add_subplot(111, projection='3d')
ax.set_zmargin(1) # Add a bit more space around the plot.
ax.plot_wireframe(x_plt, y_plt, z_plt,
rstride=1, cstride=1, # "Resolution" of the plot
color='blue', linewidth=1.0,
alpha=0.7, antialiased=True)
# Tilt the view to match the example.
ax.view_init(elev = 45, azim = -45)
plt.xlabel('i')
plt.ylabel('x')
plt.title('test')
plt.show()
这是生成的图像。我不得不将 n
减少到 80 以使其完全可以理解,而且我不知道我在看什么,所以我不确定它是否正确。但我认为它看起来与您提供的示例大致相似。
为了说明这种方法的强大功能,这里有一个鹦鹉螺 shell。它使用两阶段参数化,可以压缩,但我发现它在概念上更清晰:
n_ticks = 100
# Abstract u and v parameters describing surface coordinates
u_plt = np.arange(n_ticks // 2) * 2
v_plt = np.arange(n_ticks)
# theta is the angle along the leading edge of the shell
# phi is the angle along the spiral of the shell
# r is the distance of the edge from the origin
theta_plt = np.pi * ((u_plt / n_ticks) * 0.99 + 0.005)
phi_plt = np.pi * v_plt / (n_ticks / 5)
r_plt = v_plt / (n_ticks / 5)
# These formulas are based on the formulas for rendering
# a sphere parameterized by theta and phi. The only difference
# is that r is variable here too.
x_plt = r_plt[:, None] * np.cos(phi_plt[:, None]) * np.sin(theta_plt[None, :])
y_plt = r_plt[:, None] * np.sin(phi_plt[:, None]) * np.sin(theta_plt[None, :])
z_plt = r_plt[:, None] * \
(np.ones(np.shape(phi_plt[:, None])) * np.cos(theta_plt[None, :]))
# This varies the color along phi
colors = cm.inferno(1 - (v_plt[:, None] / max(v_plt))) * \
np.ones(np.shape(u_plt[None, :, None]))
fig = plt.figure(figsize=(8, 8))
ax = fig.add_subplot(111, projection='3d')
ax.set_zmargin(1)
ax.plot_surface(x_plt, y_plt, z_plt,
rstride=1, cstride=1,
facecolors=colors, linewidth=1.0,
alpha=0.3, antialiased=True)
ax.view_init(elev = 45, azim = -45)
plt.show()