2013-11-15 10 views
0

Я новичок в программировании на python. Я пытаюсь показать поверхностный сюжет, изменив пример, найденный на веб-сайте matplotlib. Можете ли вы сказать мне, что случилось?Problemw with python surface plot

Мой код:

import matplotlib.pyplot as plt 
from matplotlib import cm 
import numpy 

def H(n, f, l, delta, H_abs, H_ph): 
    c0 = 2.99796e8 
    n0 = 1.00027 + 0j 
    n1 = complex(n[0], n[1]) 

    Sum = 0 
    for i in range(1, delta+1): 
     Sum = Sum + ((n0-n1)*exp(complex(0,-1*2*pi*f*n1*l/c0))/(n1+n0))**i 

    H_Theo = 4*n0*n1*exp(complex(0,2*pi*f*l)*(n0-n1)/c0)*(1+Sum)/(n0+n1) 

    M = abs(H_Theo) - H_abs 
    A = cmath.phase(H_Theo) - H_ph 

    return abs(M) + abs(A) 

freq = 1213188709257.4814 
l_real = 6.77e-4 
d = 0 
H_abs = 0.798653104536778 
H_ph = 2.1845744701729926 

n_test = numpy.arange(1.5, 2.5, 0.01).tolist() 
k_test = numpy.arange(-0.05, 0.05, 0.001).tolist() 

X = n_test 
Y = k_test 
X, Y = numpy.meshgrid(X, Y) 

errore = [] 
for i in range(len(n_test)): 
    errore.append(H([X[i],Y[i]], freq, l_real, d, H_abs, H_ph)) 

Z = errore 

fig2 = plt.figure() 
az = fig2.gca(projection='3d') 
az.plot_surface(X, Y, Z, rstride=8, cstride=8, alpha=0.3) 
cset = az.contour(X, Y, Z, zdir='z', offset=min(Z)-1, cmap=cm.coolwarm) 
cset = az.contour(X, Y, Z, zdir='x', offset=min(X)-1, cmap=cm.coolwarm) 
cset = az.contour(X, Y, Z, zdir='y', offset=max(Y)+0.05, cmap=cm.coolwarm) 

az.set_xlabel('n') 
az.set_xlim(min(X)-1, max(X)+1) 
az.set_ylabel('k') 
az.set_ylim(min(Y)-0.05, max(Y)+0.05) 
az.set_zlabel('Err') 
az.set_zlim(min(Z)-1, max(Z)+1) 

plt.show() 

Ошибки я получаю:

n1 = complex(n[0], n[1]) 
TypeError: only length-1 arrays can be converted to Python scalars 

Я видел другие Q & А по этому вопросу, но я не смог решить эту проблему, в любом случае.

Может быть, вопрос тривиален, но я буду очень признателен за любую помощь для того, чтобы быть в состоянии увидеть график, который, в конце концов, должно оказаться подобными этой: http://matplotlib.org/examples/mplot3d/contour3d_demo3.html

ответ

2

Вашей проблема в том, что X [i] и Y [i] - 1-й массив, который вы передаете в H как n. I.e., n = [X [i], Y [i]]. Затем вы вызываете complex (n [0], n [1]), который ожидает скалярные аргументы, а не массивы. Если вы намереваетесь, чтобы n было 1-мерным массивом комплексных чисел, вы можете написать n = n [0] + 1j * n [1]. Однако вам все равно нужны изменения для остальной части вашего кода. Вы потеряли некоторый импорт и, кажется, предположили «от numpy import *»

Во всяком случае, я внес достаточные изменения, чтобы запустить его и построить что-то, но я действительно сомневаюсь, что это то, что вы находясь в поиске. Вам нужно подумать о том, какую функцию вы пытаетесь построить.

from mpl_toolkits.mplot3d import axes3d 
import matplotlib.pyplot as plt 
from matplotlib import cm 
import numpy 

def H(n, f, l, delta, H_abs, H_ph): 
    c0 = 2.99796e8 
    n0 = 1.00027 + 0j 
    n1 = n[0] + 1j * n[1] 

    Sum = 0 
    for i in range(1, delta+1): 
     Sum = Sum + ((n0-n1)*numpy.exp(-1*2*numpy.pi*f*n1*l/c0)/(n1+n0))**i 

    H_Theo = 4*n0*n1*numpy.exp(2*numpy.pi*f*l*(n0-n1)/c0)*(1+Sum)/(n0+n1) 

    M = numpy.abs(H_Theo) - H_abs 
    A = numpy.angle(H_Theo) - H_ph 

    return abs(M) + abs(A) 

freq = 1213188709257.4814 
l_real = 6.77e-4 
d = 0 
H_abs = 0.798653104536778 
H_ph = 2.1845744701729926 

n_test = numpy.arange(1.5, 2.5, 0.01).tolist() 
k_test = numpy.arange(-0.05, 0.05, 0.001).tolist() 

X = n_test 
Y = k_test 
X, Y = numpy.meshgrid(X, Y) 

errore = [] 
for i in range(len(n_test)): 
    errore.append(H([X[i],Y[i]], freq, l_real, d, H_abs, H_ph)) 

Z = errore 

fig2 = plt.figure() 
az = fig2.gca(projection='3d') 
az.plot_surface(X, Y, Z, rstride=8, cstride=8, alpha=0.3) 
cset = az.contour(X, Y, Z, zdir='z', offset=numpy.min(Z)-1, cmap=cm.coolwarm) 
cset = az.contour(X, Y, Z, zdir='x', offset=numpy.min(X)-1, cmap=cm.coolwarm) 
cset = az.contour(X, Y, Z, zdir='y', offset=numpy.max(Y)+0.05, cmap=cm.coolwarm) 

az.set_xlabel('n') 
az.set_xlim(numpy.min(X)-1, numpy.max(X)+1) 
az.set_ylabel('k') 
az.set_ylim(numpy.min(Y)-0.05, numpy.max(Y)+0.05) 
az.set_zlabel('Err') 
az.set_zlim(numpy.min(Z)-1, numpy.max(Z)+1) 

plt.show() 
+0

Благодарим за предложение. Теперь возникает новая ошибка: Sum = Sum + ((n0-n1) * exp (комплекс (0, -1 * 2 * pi * f * n1 * l/c0))/(n1 + n0)) ** i TypeError: только массивы длиной-1 могут быть преобразованы в сканеры Python – user2996448

+0

Это та же ошибка. комплекс ожидает скаляров. –

+0

Тогда вы за очень быстрый ответ. Я изменил код, следуя вашим указаниям, и немного больше. Затем я рассмотрю функцию, но на данный момент у меня есть еще одна ошибка: cset = az.contour (X, Y, Z, zdir = 'z', offset = min (Z) -1, cmap = cm.coolwarm) ValueError: значение истинности массива с несколькими элементами неоднозначно. Используйте a.any() или a.all() – user2996448