Цитирование из plot_surface
документации :
X, Y, Z: значения данных в виде двумерных массивов
Но ваш Z
одномерный. Вам необходимо изменить его, чтобы он соответствовал значениям X
и Y
. Это должно работать:
Xpl = numpy.arange(xmin, xmax, 0.1).tolist()
Ypl = numpy.arange(ymin, ymax, 0.01).tolist()
Xpl, Ypl = numpy.meshgrid(Xpl, Ypl)
Z=[]
for j in range(len(Xpl)):
for i in range(len(Xpl[0])):
# your loop order was backwards
Z.append(funcPower3([Xpl[j][i],Ypl[j][i]]))
# reshape Z
Z = numpy.array(Z).reshape(Xpl.shape)
fig = plt.figure('Power 3')
ax = fig.gca(projection='3d')
surf=ax.plot_surface(Xpl, Ypl, Z, rstride=8, cstride=8, alpha=0.3,cmap=cm.jet)
ax.set_xlabel('X Label')
ax.set_ylabel('Y Label')
plt.show()
Но у вашего кода есть пара недостатков. Прежде всего, глядя на вашу функцию funcPower3
, вы читаете два файла снова и снова для каждого вызова функции. Это слишком расточительно. Вместо этого прочитайте эти параметры один раз и передайте их вашей функции в качестве параметров. Эту функцию также можно немного упростить (и попытаться следовать соглашениям об именовании PEP8 ):
def func_power_3(param, x1, y):
p1, p2 = param
res = sum(y_i - (p1*x1_i)**p2 for x1_i, y_i in zip(x1, y))
return res
а остальное будет
with open("power3X.txt","r") as infile:
x1 = [float(line) for line in infile]
with open("power3Y.txt","r") as infile:
y = [float(line) for line in infile]
xpl = numpy.arange(xmin, xmax, 0.1) # no need for .tolist()
ypl = numpy.arange(ymin, ymax, 0.01) # meshgrid can work with numpy.array's
xpl, ypl = numpy.meshgrid(xpl, ypl)
# we can form z with list comprehension
z = [[func_power_3([p1,p2], x1, y) for p1, p2 in zip(p1row, p2row)]
for p1row, p2row in zip(xpl, ypl)]
fig = plt.figure('Power 3')
ax = fig.gca(projection='3d')
surf=ax.plot_surface(xpl, ypl, z, rstride=8, cstride=8, alpha=0.3,cmap=cm.jet)
ax.set_xlabel('X Label')
ax.set_ylabel('Y Label')
plt.show()