在 2D 绘图上绘制 3D 点 从文件中读取值
Drawing 3D points on a 2D plot reading values from a file
我有一个文件,其中包含具有 3 个坐标的点集,由制表符分隔。像这样(为便于阅读而添加的空格,原始文件中不存在):
x0 \t y0 \t z0
x0 \t y1 \t z1
x1 \t y0 \t z0
x1 \t y1 \t z1
x1 \t y2 \t z2
x2 \t y0 \t z0
...
我想将它们绘制为单个二维图上的单独线条,例如:
line for all points with x=x0, label=x0
line for all points with x=x1, label=x1
line for all points with x=x2, label=x2
用不同的颜色绘制这些线条。
我知道 numpy 有一个很酷的读取列的功能,就像这样:
my_data = np.genfromtxt(input_file, delimiter='\t', skiprows=0)
Y = my_data[:, 1]
Z = my_data[:, 2]
是否有类似的快速和干净的方法来根据另一列的值选择列值?
如果没有快速函数可以做到这一点(根据它旁边的 x 值组成一列)我可以解析文件并逐步构建数据结构。
然后我会使用 Matplotlib 做这样的事情:
ax = plt.axes()
ax.set_xlabel('Y')
ax.set_ylabel('Z')
# for each value of X
# pick Y and Z values
plt.plot(Y, Z, linestyle='--', marker='o', color='b', label='x_val')
但我确信有一种更 Pythonic 的方法可以做到这一点。也许有一些列表理解的技巧?
编辑:这是完整的工作代码(感谢回答的人)。我只需要一种在不切断图例的情况下让它显示出来的方法
import os
import numpy as np
import matplotlib.pyplot as plt
input_file = os.path.normpath('C:/Users/sturaroa/Documents/my_file.tsv')
# read values from file, by column
my_data = np.genfromtxt(input_file, delimiter='\t', skiprows=0)
X = my_data[:, 0] # 1st column
Y = my_data[:, 1] # 2nd column
Z = my_data[:, 2] # 3rd column
# read the unique values in X and use them as keys in a dictionary of line properties
d = {val: {'label': 'x {}'.format(val), 'linestyle': '--', 'marker': 'o'} for val in set(X)}
# draw a different line for each of the unique values in X
for val, kwargs in d.items():
mask = X == val
y, z = Y[mask], Z[mask]
plt.plot(y, z, **kwargs)
# label the axes of the plot
ax = plt.axes()
ax.set_xlabel('Y')
ax.set_ylabel('Z')
# get the labels of all the lines in the graph
handles, labels = ax.get_legend_handles_labels()
# create a legend growing it from the middle and put it on the right side of the graph
lgd = ax.legend(handles, labels, loc='center left', bbox_to_anchor=(1.0, 0.5))
# save the figure so that the legend fits inside it
plt.savefig('my_file.pdf', bbox_extra_artists=(lgd,), bbox_inches='tight')
plt.show()
假设您有一个包含 value:kwargs
对的字典,其中 value
是 X
必须在该曲线中采用的值,而 kwargs
是一个字典保存要传递给绘图函数的参数。
下面的代码将使用 value
构造一个掩码,可用于索引和选择适当的点。
import numpy as np
import matplotlib.pyplot as plt
my_data = np.genfromtxt('data.txt', delimiter=' ', skiprows=0)
X = my_data[:, 0]
Y = my_data[:, 1]
Z = my_data[:, 2]
d = {
0: {'label': 'x0'},
1: {'label': 'x1'}
}
for val, kwargs in d.items():
mask = X == val
y, z = Y[mask], Z[mask]
plt.plot(y, z, **kwargs)
plt.legend()
plt.show()
我建议为此使用字典。从加载您的数据开始,
my_data = np.genfromtxt(input_file, delimiter='\t', skiprows=0)
X = my_data[:, 0]
Y = my_data[:, 1]
Z = my_data[:, 2]
然后用每个 x 值的数组创建一个字典:
Ydict = {}
Zdict = {}
for x in np.unique(X):
inds = X == x
Ydict[x] = Y[inds]
Zdict[x] = Z[inds]
现在你有两个字典,它们的键是 X
的唯一值(注意 np.unique
的使用),字典的值是数组 X
匹配密钥。
你的情节调用看起来像,
for x in Ydict:
plt.plot(Ydict[x], Zdict[x], label=str(x), ...)
您需要将 ...
替换为您想要设置的任何其他线条属性,但是如果您希望每条线条的颜色不同,请不要使用 color='b'
。
有帮助吗?
我有一个文件,其中包含具有 3 个坐标的点集,由制表符分隔。像这样(为便于阅读而添加的空格,原始文件中不存在):
x0 \t y0 \t z0
x0 \t y1 \t z1
x1 \t y0 \t z0
x1 \t y1 \t z1
x1 \t y2 \t z2
x2 \t y0 \t z0
...
我想将它们绘制为单个二维图上的单独线条,例如:
line for all points with x=x0, label=x0
line for all points with x=x1, label=x1
line for all points with x=x2, label=x2
用不同的颜色绘制这些线条。
我知道 numpy 有一个很酷的读取列的功能,就像这样:
my_data = np.genfromtxt(input_file, delimiter='\t', skiprows=0)
Y = my_data[:, 1]
Z = my_data[:, 2]
是否有类似的快速和干净的方法来根据另一列的值选择列值?
如果没有快速函数可以做到这一点(根据它旁边的 x 值组成一列)我可以解析文件并逐步构建数据结构。
然后我会使用 Matplotlib 做这样的事情:
ax = plt.axes()
ax.set_xlabel('Y')
ax.set_ylabel('Z')
# for each value of X
# pick Y and Z values
plt.plot(Y, Z, linestyle='--', marker='o', color='b', label='x_val')
但我确信有一种更 Pythonic 的方法可以做到这一点。也许有一些列表理解的技巧?
编辑:这是完整的工作代码(感谢回答的人)。我只需要一种在不切断图例的情况下让它显示出来的方法
import os
import numpy as np
import matplotlib.pyplot as plt
input_file = os.path.normpath('C:/Users/sturaroa/Documents/my_file.tsv')
# read values from file, by column
my_data = np.genfromtxt(input_file, delimiter='\t', skiprows=0)
X = my_data[:, 0] # 1st column
Y = my_data[:, 1] # 2nd column
Z = my_data[:, 2] # 3rd column
# read the unique values in X and use them as keys in a dictionary of line properties
d = {val: {'label': 'x {}'.format(val), 'linestyle': '--', 'marker': 'o'} for val in set(X)}
# draw a different line for each of the unique values in X
for val, kwargs in d.items():
mask = X == val
y, z = Y[mask], Z[mask]
plt.plot(y, z, **kwargs)
# label the axes of the plot
ax = plt.axes()
ax.set_xlabel('Y')
ax.set_ylabel('Z')
# get the labels of all the lines in the graph
handles, labels = ax.get_legend_handles_labels()
# create a legend growing it from the middle and put it on the right side of the graph
lgd = ax.legend(handles, labels, loc='center left', bbox_to_anchor=(1.0, 0.5))
# save the figure so that the legend fits inside it
plt.savefig('my_file.pdf', bbox_extra_artists=(lgd,), bbox_inches='tight')
plt.show()
假设您有一个包含 value:kwargs
对的字典,其中 value
是 X
必须在该曲线中采用的值,而 kwargs
是一个字典保存要传递给绘图函数的参数。
下面的代码将使用 value
构造一个掩码,可用于索引和选择适当的点。
import numpy as np
import matplotlib.pyplot as plt
my_data = np.genfromtxt('data.txt', delimiter=' ', skiprows=0)
X = my_data[:, 0]
Y = my_data[:, 1]
Z = my_data[:, 2]
d = {
0: {'label': 'x0'},
1: {'label': 'x1'}
}
for val, kwargs in d.items():
mask = X == val
y, z = Y[mask], Z[mask]
plt.plot(y, z, **kwargs)
plt.legend()
plt.show()
我建议为此使用字典。从加载您的数据开始,
my_data = np.genfromtxt(input_file, delimiter='\t', skiprows=0)
X = my_data[:, 0]
Y = my_data[:, 1]
Z = my_data[:, 2]
然后用每个 x 值的数组创建一个字典:
Ydict = {}
Zdict = {}
for x in np.unique(X):
inds = X == x
Ydict[x] = Y[inds]
Zdict[x] = Z[inds]
现在你有两个字典,它们的键是 X
的唯一值(注意 np.unique
的使用),字典的值是数组 X
匹配密钥。
你的情节调用看起来像,
for x in Ydict:
plt.plot(Ydict[x], Zdict[x], label=str(x), ...)
您需要将 ...
替换为您想要设置的任何其他线条属性,但是如果您希望每条线条的颜色不同,请不要使用 color='b'
。
有帮助吗?