3d表面图genfromtxt

时间:2014-06-04 11:41:37

标签: python 3d

我在通过阅读文本文件绘制三维表面图时遇到了问题。问题是,我正在使用不同的数据类型,如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

2 个答案:

答案 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()