我必须绘制一个具有无意义负值的3d函数(它们不应出现在图中)。必须绘制的函数如下:
def constraint_function(x, y):
return min(
(1800 - 0.3 * x - 0.5 * y) / 0.4,
(500 - 0.1 * x - 0.08 * y) / 0.12,
(200 - 0.06 * x - 0.04 * y) / 0.05
)
我按照以下方式计算功能:
xs = np.linspace(0, 3600, 1000)
ys = np.linspace(0, 3600, 1000)
zs = np.empty(shape=(1000, 1000))
for ix, x in enumerate(xs):
for iy, y in enumerate(ys):
zs[ix][iy] = constraint_function(x, y)
xs, ys = np.meshgrid(xs, ys)
该函数的有效值大多在平方[0, 3600]x[0, 3600]
中。我的第一种方法是设置轴限制以满足我的需要:
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.azim = 20
ax.set_xlim(0, 3500)
ax.set_ylim(0, 3500)
ax.set_zlim(0, 4500)
ax.plot_surface(xs, ys, zs)
plt.show()
结果如下:
它只是忽略了限制并且无论如何都绘制了它。第二种方法是将负值定义为np.nan
,将函数更改为:
def constraint_function(x, y):
temp = min(
(1800 - 0.3 * x - 0.5 * y) / 0.4,
(500 - 0.1 * x - 0.08 * y) / 0.12,
(200 - 0.06 * x - 0.04 * y) / 0.05
)
return temp if temp >= 0 else np.nan
并将无效值的alpha设置为零:
plt.cm.jet.set_bad(alpha=0.0)
ax.azim = 20
ax.set_xlim(0, 3500)
ax.set_ylim(0, 3500)
ax.set_zlim(0, 4500)
ax.plot_surface(xs, ys, zs)
plt.show()
答案 0 :(得分:1)
首先,你的z值数组轴是相反的;它应该是zs[iy][ix]
而不是zs[ix][iy]
。因此,你的情节是左右翻转的。
其次,通过在Python中迭代来构建z数组要慢得多;你应该代之以numpy,就像这样:
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
# create axis sample
xs = np.linspace(0, 3600, 1000)
ys = np.linspace(0, 3600, 1000)
# create mesh samples
xxs, yys = np.meshgrid(xs, ys)
# create data
zzs = np.min([
((1800 - 0.30 * xxs - 0.50 * yys) / 0.40),
(( 500 - 0.10 * xxs - 0.08 * yys) / 0.12),
(( 200 - 0.06 * xxs - 0.04 * yys) / 0.05)
], axis=0)
# clip data which is below 0.0
zzs[zzs < 0.] = np.NaN
NumPy矢量化操作要快很多倍。
第三,除了采样分辨率太低外,你的代码没有什么特别的错误;把它设得更高,
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.azim = 20
ax.set_xlim(0, 3500)
ax.set_ylim(0, 3500)
ax.set_zlim(0, 4500)
ax.plot_surface(xxs, yys, zzs, rcount=200, ccount=200)
plt.show()
产生
答案 1 :(得分:0)
从技术上讲,你可以倾斜网格,这样会导致zick-zack模式的网格点移动,使它们位于一条直线上。
如下所示。
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
x=np.linspace(-5,5,6)
X,Y = np.meshgrid(x,x)
Z = X+Y
X[Z==-2] = X[Z==-2]+1
Y[Z==-2] = Y[Z==-2]+1
Z[Z==-2] = 0
Z[Z<0] = np.nan
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.set_zlim(0, 12)
ax.plot_surface(X, Y, Z)
plt.show()
现在的问题是将此方法推广到任意曲面。它确实可行但需要一些工作。