Python - Как построить трехмерную диаграмму рассеяния внутри функции без интерпретации Z-ввода как аргумента RGBA в Python? - PullRequest
0 голосов
/ 22 сентября 2018

Я долгое время программист MATLAB, пытающийся изучать Python.Я пытаюсь построить трехмерный график рассеяния внутри функции, которая вычисляет центр тяжести.

Я хорошо нарисовал 1D и 2D.В 3D я могу построить CoG (одна точка).Я также могу построить координаты x и y моих масс в 3D (ax.scatter (xNum, yNum)).Но когда я помещаю в список массовых позиций Z (ax.scatter (xNum, yNum, zNum)), я получаю следующую ошибку:

повышение ValueError («Недопустимый аргумент RGBA: {! R}». Format(orig_c))

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

Чем отличается выполнение этого внутри функции?Как я могу заставить Python распознать третий ввод - это список позиций, а не аргумент RGBA?Это на самом деле то, что происходит?

Вот мой код, немного очищенный для удобства чтения:

Код оболочки:

import numpy as np
from sympy import Symbol, simplify
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import math

# Define Initial Values
m = [5,3,7,5,8,9,6,1,6,8]
x = [5,3,7,5,8,9,6,15,6,8]
y = [4,9,7,1,1,14,10,3,11,11]
z = [6,3,5,1,6,13,1,3,6,11]
SymOrNo = 1

# Run Tests
print ('*****This code tests the CoG1D, CoG2D, and CoG3D functions*****')

print('\n\n\n','CoG3D Test (Numeric):')
CoG = CoG3D(m,x,y,z,0)

Код участка:

# Make Plot
fig = plt.figure()
ax = fig.add_subplot(111,projection='3d')

# START TEST PLOT
n = 100
xs = np.random.randint(0, 10, size=n)
ys = np.random.randint(0, 10, size=n)
zs = np.random.randint(0, 10, size=n)
colors = np.random.randint(0, 10, size=n)
ax.scatter(xs, ys, zs, c=colors, marker='o')
# END TEST PLOT

#CGmark, = ax.scatter(CoGnumX,CoGnumY,CoGnumZ, 'b')  #<-- My actual plot code
ax.scatter(xNum,yNum,zNum, c = 'r', marker = 'o')    #<-- My actual plot code
plt.title('3D Center of Gravity')
ax.set_xlabel('X position [m]')
ax.set_ylabel('Y position [m]')
ax.set_zlabel('Z position [m]')
#plt.legend(( CGmark),('Masses','Center of Gravity'))

plt.show()
return  CoG

Прямо сейчас, функция выдает ошибку на «Тестовом графике» с недопустимым аргументом RGBA, но комментирование этого означает, что такая же ошибка происходит с моим реальным кодом.

Полная функция:

def CoG3D(m,x,y,z,SymOrNo):
''' 3D Center of Gravity Computation '''
## Inputs:
##       -   m       [1xn]  [kg]   :: row vector of masses  
##       -   x       [1xn]  [m]    :: row vector of mass x positions
##       -   y       [1xn]  [m]    :: row vector of mass y positions
##       -   z       [1xn]  [m]    :: row vector of mass z positions  
##       -   SymOrNo [~]    [~]    :: binary choice: '1' lengths defined symbolically, '0' lengths defined numerically

x = np.array(x)+1         # distance of each mass from the left edge
y = np.array(y)+1         # distance of each mass from the bottom edge
z = np.array(y)+1         # distance of each mass from the back edge

# Compute Center of Gravity
mTot = np.sum(m)                                                              # total mass of all the drinks
print("Total Mass = ", mTot, '[kg]')  
numerX = np.sum(np.multiply(m,x))             # element-wise multiplication of m and x, then sum these weighted distances
numerY = np.sum(np.multiply(m,y))             # element-wise multiplication of m and x, then sum these weighted distances
numerZ = np.sum(np.multiply(m,z))             # element-wise multiplication of m and x, then sum these weighted distances
CoGx =  (numerX) / (mTot)  - 1                # Center of Gravity computation. Subtract one to account for the offset added earlier
CoGy =  (numerY) / (mTot)  - 1
CoGz =  (numerZ) / (mTot)  - 1                # Center of Gravity computation. Subtract one to account for the offset added earlier
CoG = [CoGx,CoGy,CoGz]
print('Center of Gravity = ',CoG, ' [m] ')


''' Plot Center of Gravity Result'''
# Define Plot Values
if SymOrNo == 1:
  CoGnumY = simplify(((numerY) / (mTot)  - 1).subs(L,1))
  CoGnumX = simplify(((numerX) / (mTot)  - 1).subs(L,1))
  CoGnumZ = simplify(((numerZ) / (mTot)  - 1).subs(L,1))
  print('Center of Gravity assuming L = 1: ',CoGnumX,' , ',CoGnumY,' , ',CoGnumZ, ' [m]')
else: 
  CoGnumY = ((numerY) / (mTot)  - 1)
  CoGnumX = ((numerX) / (mTot)  - 1)
  CoGnumZ = ((numerZ) / (mTot)  - 1)
xNum = np.array(simplify(x-1).subs(L,1)) # substitute 1 for L in x so distances can be plotted. Subtract 1 from x to account for the offset added earlier
yNum = np.array(simplify(y-1).subs(L,1))
zNum = np.array(simplify(z-1).subs(L,1))

lenM   = len(m)
mDev   = m - mTot / lenM # determine size of each mass relative to the others (mass percentage of total)

# Make Plot
fig = plt.figure()
ax = fig.add_subplot(111,projection='3d')

# START TEST PLOT
n = 100
xs = np.random.randint(0, 10, size=n)
ys = np.random.randint(0, 10, size=n)
zs = np.random.randint(0, 10, size=n)
colors = np.random.randint(0, 10, size=n)
ax.scatter(xs, ys, zs, c=colors, marker='o')
# END TEST PLOT

#CGmark, = ax.scatter(CoGnumX,CoGnumY,CoGnumZ, 'b')
ax.scatter(xNum,yNum,zNum, c = 'r', marker = 'o')
plt.title('3D Center of Gravity')
ax.set_xlabel('X position [m]')
ax.set_ylabel('Y position [m]')
ax.set_zlabel('Z position [m]')
#plt.legend(( CGmark),('Masses','Center of Gravity'))

plt.show()
return  CoG

И если вам интересно, почему я пересчитываю CoGnumX вместо того, чтобы просто использовать CoGx, это потому, что Python решил забыть, что CoGx был из 10 или болеетак линии назад, и не может быть принужден к запоминанию.Так что, если вам случится узнать, что является источником этой неприятности, я был бы признателен также за это выяснить.

Я искал это покрытие и нигде не нашел его.Надеюсь, это не излишне.Заранее спасибо всем, кто может помочь.:)

...