我在通过阅读文本文件绘制三维表面图时遇到了问题。问题是,我正在使用不同的数据类型,如float,int和string ..我已经附加了要解析的示例数据的代码..我很感激与代码的任何注释,使其功能... < / p>
我现在得到的错误是ValueError:元组的大小必须匹配字段数。
Thnx提前......
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from numpy import genfromtxt
fig = plt.figure(figsize=(12,12))
ax = fig.add_subplot(111, projection='3d') #ax = Axes3D(fig)
ax.set_title("Plot 3d",fontsize=14)
ax.set_xlabel('Voltage (V)', fontsize=12)
ax.set_ylabel('Pulse Delay(ms)', fontsize=12)
ax.set_zlabel('Pulse Width(ms)', fontsize=12)
ax.grid(True, linestyle='-', color='0.75')
x,y,z,m =genfromtxt('sample.txt', dtype=[('col1', 'f15'), ('col2', 'i15'), ('col3', 'i15'), ('col4', 'S15')], unpack=True)
use_colours = []
for tmp in m:
if tmp=='PASS':
use_colours.append('g')
else:
use_colours.append('r')
ax.scatter(x,y,z, s=50, c=use_colours, marker = 'o', linewidths=0);
plt.show()
sample.txt
6.000000 15.000000 21.000000 PASS
6.000000 15.000000 53.000000 PASS
6.000000 15.000000 91.000000 PASS
6.000000 15.000000 104.000000 PASS
答案 0 :(得分:0)
在尝试执行代码时,我发现了一些在不知道matplotlib
库正常运行的情况下难以防止的误用。
这是一个有效的评论代码:
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
fig = plt.figure(figsize=(12, 12))
ax = Axes3D(fig) # ax = fig.add_subplot(111, projection='3d')
ax.set_title("Plot 3d",fontsize=14)
ax.set_xlabel('Voltage (V)', fontsize=12)
ax.set_ylabel('Pulse Delay(ms)', fontsize=12)
ax.set_zlabel('Pulse Width(ms)', fontsize=12)
ax.grid(True, linestyle='-', color='0.75')
# 'i15' and 'f15' are not known as numerical types.
# You can use only 'i8' (np.int64) and 'f16' (np.float128) or 'f8' (np.float64).
# 'f16' seems not to be recognized as a valid type for the scatter library.
# I think that 'f8' and 'i8' are quoit enough.
data = np.genfromtxt('./sample.txt', dtype=[('col1', 'f8'), ('col2', 'i8'), ('col3', 'i8'), ('col4', 'S15')])
# scatter does not take for the c option a list of colours such as ['g', 'g', 'r', ...].
# In this case, we will define data for each colour, not a color for each scatter point.
m = data["col4"]
data1 = data[m == "PASS"]
data2 = data[m != "PASS"]
for dat, color in [(data1, 'g'), (data2, 'r')]:
# Don't forget that having empty data columns may raise exceptions ...
try:
x, y, z = dat['col1'], dat['col2'], dat['col3']
ax.scatter(xs=x, ys=y, zs=z, s=50, c=color, marker='o', linewidths=0)
except:
pass
plt.show()
答案 1 :(得分:0)
您获得的错误代码表明您在某些时候传递的信息不符合变量。这似乎来自genfromtxt调用中的unpack = true标志。看一些关于genfromtxt的文档,看来使用unpack = True标志会导致&#34;返回的数组被转置,因此可以使用x,y,z = loadtxt(...)&解压缩参数#34;最终导致您的x,y,z和m值看起来像:
x = (6.0, 15, 21, 'PASS')
y = (6.0, 15, 53, 'PASS')
z = (6.0, 15, 91, 'PASS')
m = (6.0, 15, 104, 'PASS')
这些值显然不适用于代码中的内容。有趣的是,只有在sample.txt中有4行并尝试解包4个变量时,这才有效。
对此的解决方案是不标记unpack = true。相反,这样的事情应该有效:
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
## takes a matrix and a column index, returns a list of the values
## in that column
def column(matrix, i):
return [row[i] for row in matrix]
fig = plt.figure(figsize=(12,12))
ax = fig.add_subplot(111, projection='3d') #ax = Axes3D(fig)
ax.set_title("Plot 3d",fontsize=14)
ax.set_xlabel('Voltage (V)', fontsize=12)
ax.set_ylabel('Pulse Delay(ms)', fontsize=12)
ax.set_zlabel('Pulse Width(ms)', fontsize=12)
ax.grid(True, linestyle='-', color='0.75')
## Your original call
#x,y,z,m =genfromtxt('sample.txt', delimiter="""", dtype=[('col1', 'f15'),
##('col2','i15'), ('col3', 'i15'), ('col4', 'S15')], unpack=True)
## The modified call
data = np.genfromtxt('sample.txt',
delimiter='\t',
usecols=(0,1,2,3),
dtype=[('col1', 'f15'),
('col2', 'i15'),
('col3', 'i15'),
('col4', 'S15')])
## split the data so that each column in the 2d array ends up in a variable.
## There is a numpy way of doing this, you should look into that
x = column(data, 0)
y = column(data, 1)
z = column(data, 2)
m = column(data, 3)
use_colours = []
for tmp in m:
if tmp=='PASS':
use_colours.append('g')
else:
use_colours.append('r')
## Let's make sure the values look like we expect:
print x
print "\n"
print y
print "\n"
print z
print "\n"
print m
ax.scatter(x,y,z, s=50, c=use_colours, marker = 'o', linewidths=0);
plt.show()