Python:从第二列和第三列绘制,同时从第一列中选择参数值
Posted
技术标签:
【中文标题】Python:从第二列和第三列绘制,同时从第一列中选择参数值【英文标题】:Python: Plot from second and third columns while picking parameter values from the first one 【发布时间】:2022-01-15 21:47:04 【问题描述】:我在一个名为“sample1.dat”的文件中有一个三列数据,以及一个读取这些列并尝试绘制第三列与第二列的代码的代码。我从第一列元素中提取参数值,只要它们的值保持不变。
“sample1.dat”读取
0 1 1
0 2 4
0 3 9
0 4 16
0 5 25
0 6 36
1 1 1
1 2 8
1 3 27
1 4 64
1 5 125
1 6 216
2 1 1
2 2 16
2 3 81
2 4 256
2 5 625
2 6 1296
还有我的代码:
import matplotlib.pyplot as plt
import numpy as np
data = np.loadtxt('sample1.dat')
x = data[:,0]
y = data[:,1]
z = data[:,2]
L = len(data)
col = ['r','g','b']
x0 = x[0]; j=0; jold=-1
for i in range(L):
print('j, col[j]=',j, col[j])
if x[i] == x0:
print('y[i], z[i]=',y[i],z[i])
if i==0 or j != jold: # j-index decides new or the same paramet
label = 'parameter = '.format(x0)
else:
label = ''
print('label =',label)
plt.plot(y[i], z[i], color=col[j], marker='o', label=label)
else:
x0 = x[i] # Update when x-value changes,
# i.e. pick up the next parameter value
i -= 1 # Shift back else we miss the 1st point for new x-value
j += 1; jold = j
plt.legend()
plt.xlabel('2nd column')
plt.ylabel('3rd column')
plt.savefig('sample1.png')
plt.show()
剧情结局:
可以清楚地看到两个问题仍然存在:
虽然我试图避免在我的代码中重复出现,但图例仅出现在第一个参数中。
虽然图例显示线加标记图,但默认线型未出现。
我该如何解决这些问题,或者是否有更聪明的编码方式来实现相同的目的。
【问题讨论】:
【参考方案1】:通过使用 pandas 和 seaborn,您可以在几行代码中得到您想要的结果。
如果您将列名(例如A
、B
和C
)添加到sample1.dat
文件中的数据,如下所示:
A B C
0 1 1
0 2 4
0 3 9
0 4 16
0 5 25
0 6 36
1 1 1
1 2 8
1 3 27
1 4 64
1 5 125
1 6 216
2 1 1
2 2 16
2 3 81
2 4 256
2 5 625
2 6 1296
然后,您可以将数据加载到 pandas 数据框中并使用 seaborn 进行绘制:
import pandas as pd
import seaborn as sns
df=pd.read_fwf('sample1.dat')
col = ['r','g','b']
sns.scatterplot(data=df,x='B',y='C',hue='A',palette=col)
输出给出:
【讨论】:
或许您可以通过df = pd.read_fwf(..., header=None, names=['A','B','C'])
读取原始文件(无需在文件中添加列名)
好点,这绝对是一种无需修改文件即可加载数据的更好方法
谢谢。抱歉@jylls,read_fwf
在这里做什么?其次,我没有从你的代码中得到任何点。 @JohanC 的建议显示了一些点,但它们是错误的,并且 y 轴刻度显示一些垃圾字体!
read_fwf
是一个 pandas 函数,可以读取您的数据文件并将其转换为数据帧。确保您的数据格式与我的答案中的格式相同,并且文件名称相同。要显示情节,您可能需要致电 plt.show
【参考方案2】:
第一个问题是由于涉及j
、jold
和x0
的一些奇怪逻辑。可以通过一次为每个 x 值绘制所有 y,z
来简化代码。 Numpy 允许选择与给定x0
对应的y
作为y[x==x0s]
。
第二个问题可以通过显式设置所需的线型来解决,即ls=''
。
import matplotlib.pyplot as plt
import numpy as np
data = np.loadtxt('sample1.dat')
x = data[:, 0]
y = data[:, 1]
z = data[:, 2]
colors = ['r', 'g', 'b']
for x0, color in zip(np.unique(x), colors):
plt.plot(y[x == x0], z[x == x0], color=color, marker='o', ls='', label=f'parameter = x0:.0f')
plt.legend()
plt.xlabel('2nd column')
plt.ylabel('3rd column')
plt.show()
另一种方法是使用 seaborn 库,它无需大量干预即可进行选择和着色,例如:
import seaborn as sns
sns.scatterplot(x=y, y=z, hue=x, palette=['r', 'g', 'b'])
如果将数据组织为字典或 pandas 数据框,Seaborn 可以自动添加标签:
data = 'first column': x.astype(int),
'second column': y,
'third column': z
sns.scatterplot(data=data, x='second column', y='third column', hue='first column', palette=['r', 'g', 'b'])
【讨论】:
在编辑您的答案时,请随时参考我的答案。谢谢@JohanCpan> 对不起,我在编辑我的时候没有注意到你的回答。你的方法当然是一个好方法,干得好。 Seaborn 非常适合这种类型的地块。 不用担心。谢谢,我很感激。 @JohanC 感谢和抱歉迟到的回复。您的版本完美运行。以上是关于Python:从第二列和第三列绘制,同时从第一列中选择参数值的主要内容,如果未能解决你的问题,请参考以下文章