简体   繁体   中英

'float' has no attribute dtype

I have a set of data and I have fit a normal distribution to the data using numpy and scipy. But when I try to plot the pdf, I get the following error:

错误说明

I have tried to change the dtype of Z, but that did not work. Any suggestions will help. Thanks.

import matplotlib.pyplot as plt
from mpl_toolkits import mplot3d
import numpy as np
import random 
from sympy.matrices import Matrix
from sympy import symbols, pprint, N
from scipy.stats import multivariate_normal
from target import true_target_trajectory, target_posiion

def plot_gaussian(X, Y, Z):
    fig = plt.figure()
    ax = fig.add_subplot(111, projection='3d')
    ax.plot_surface(X, Y, Z)
    plt.show()

def covariance(x, y):
    sigma1 = np.std(x, dtype=np.float64)
    sigma2 = np.std(y, dtype=np.float64)
    cov = np.matrix([[sigma1, sigma1*sigma2], [sigma1*sigma2, sigma2]])
    min_eig = np.min(np.real(np.linalg.eigvals(cov)))
    if min_eig < 0:
        cov -= 10*min_eig * np.eye(*cov.shape)
    return cov

def gaussian(x, mu, cov):
    rv = multivariate_normal(mu, cov)
    return rv.pdf(x)

#plot_gaussian()
vin = 300
qin = 9
x = []
y = []
time = np.linspace(0, 2*np.pi, 100)
for t in (time):
    cc = target_posiion(vin, qin, t)
    x.append(cc.T[0])
    y.append(cc.T[1])
mu = np.array([np.mean(x), np.mean(y)])
cov = covariance(x, y)
X, Y = np.meshgrid(x, y)
pos = np.dstack((X, Y))
Z = gaussian(pos, mu, cov)
plot_gaussian(X, Y, Z)

I tried to reproduce the issue with x = np.linspace(-1, 3, 100) and y = np.linspace(0, 4, 100). But that did not give any error and i got the bell curve as expected. So i am attaching the code for target position. The code for target_position:

import random
import numpy as np
from sympy.vector.coordsysrect import CoordSys3D
from sympy.physics.mechanics import dynamicsymbols
from sympy import symbols, sin, pprint, Derivative, Identity, N
from sympy.matrices import Matrix, BlockMatrix, block_collapse

C = CoordSys3D('C')
i, j, k = C.base_vectors()

def evaluate_matrix(m, v_in, q_in, tk):
    w, t = symbols('w t')
    v0, q = symbols('v0 q')
    params = {v0:v_in, q:q_in, t:tk}
    return Matrix([[N(m[0].subs(params)), N(m[1].subs(params))]]).T

def true_target_trajectory(v_in, q_in, tk):
    w, t = symbols('w t')
    v0, q, A = symbols('v0 q A')
    r, v, a, x, y = dynamicsymbols('r v a x y')
    A = (v0**2)/q
    w = q/(2*v0)
    x = A*sin(w*t)*i
    y = A*sin(2*w*t)*j
    r = x + y
    r_m = Matrix(r.to_matrix(C)[:2])
    v = Derivative(r, t).doit()
    v_m = Matrix(v.to_matrix(C)[:2])
    a = Derivative(v, t).doit()
    a_m = Matrix(a.to_matrix(C)[:2])
    x_k = BlockMatrix([[r_m.T, v_m.T, a_m.T]]).T
    I = Identity(2)
    H = BlockMatrix([[I, I, I]])
    z = evaluate_matrix(block_collapse(H*x_k), v_in, q_in, tk)
    return z

def target_posiion(v_in, q_in, tk):
    sigma = 50
    u_k = Matrix([[random.gauss(0,1), random.gauss(0,1)]]).T
    z = true_target_trajectory(v_in, q_in, tk)
    z_c_k = z + sigma*u_k
    return z_c_k

The problem

The problem is that your x and y are lists of type sympy.core.numbers.Float , not regular Python float . Numpy doesn't know how to convert Sympy numeric types, so meshgrid ends up returning X and Y arrays of dtype=object . Down the line, this ends up screwing up the call to ax.plot_surface .

The fix

Just convert x and y to standard Numpy arrays of np.float64 before you pass them into meshgrid :

X, Y = np.meshgrid(np.array(x).astype(float), np.array(y).astype(float))

Once you do that, everything should be fine. Here's the output:

在此处输入图片说明

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM