在matplotlib中,有没有一种方法可以固定或排列具有字符和数字的混合类型的x值的顺序?

In matplotlib, is there a method to fix or arrange the order of x-values of a mixed type with a character and digits?

matplotlib 中有多个 Q/A x 值,当 x 值为 int 或 float 时,matploblit 会按照 x 的正确顺序绘制图形。例如,在字符类型中,绘图按

的顺序显示 x 值
1 15 17 2 21 7 etc

但是当它变成int时,就变成了

1 2 7 15 17 21 etc

以人为本。 如果 x 值与字符和数字混合,例如

NN8 NN10 NN15 NN20 NN22 etc

剧情会按照

的顺序出现
NN10 NN15 NN20 NN22 NN8 etc

有没有办法在不删除 x 值中的 'NN' 的情况下修复 x 值在人工顺序或 x 列表中的现有顺序。

更详细地说,xvalues 是目录名并在 linux 函数中使用 grep 排序,结果在 linux 终端中显示如下,可以保存在文本文件中。

joonho@login:~/NDataNpowN$ get_TEFrmse NN 2 | sort -n -t N -k 3
NN7 0.3311
NN8 0.3221
NN9 0.2457
NN10 0.2462
NN12 0.2607
NN14 0.2635

不排序,linuxshell也显示在机器顺序如

NN10 0.2462
NN12 0.2607
NN14 0.2635
NN7 0.3311
NN8 0.3221
NN9 0.2457

正如我所说,pandas 比处理基础 Python 列表等更容易完成此任务:

import matplotlib.pyplot as plt
import pandas as pd

#imports the text file assuming that your data are separated by space, as in your example above
df = pd.read_csv("test.txt", delim_whitespace=True, names=["X", "Y"])
#extracting the number in a separate column, assuming you do not have terms like NN1B3X5
df["N"] = df.X.str.replace(r"\D", "", regex=True).astype(int)
#this step is only necessary, if your file is not pre-sorted by Linux
df = df.sort_values(by="N")

fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 6))

#categorical plotting
df.plot(x="X", y="Y", ax=ax1)
ax1.set_title("Evenly spaced")

#numerical plotting
df.plot(x="N", y="Y", ax=ax2)
ax2.set_xticks(df.N)
ax2.set_xticklabels(df.X)
ax2.set_title("Numerical spacing")

plt.show()

示例输出:

既然你问过是否有非 pandas 解决方案 - 当然。 Pandas 让一些事情变得更加方便。在这种情况下,我会恢复到 numpy。 Numpy是matplotlib的依赖,所以相对于pandas,必须安装,如果你使用matplotlib:

import matplotlib.pyplot as plt
import numpy as np
import re

#read file as strings
arr = np.genfromtxt("test.txt", dtype="U15")
#remove trailing strings
Xnums = np.asarray([re.sub(r"\D", "", i) for i in arr[:, 0]], dtype=int)
#sort array 
arr = arr[np.argsort(Xnums)]
#extract x-values as strings...
Xstr = arr[:, 0]
#...and y-values as float
Yvals = arr[:, 1].astype(float)

fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 6))

#categorical plotting
ax1.plot(Xstr, Yvals)
ax1.set_title("Evenly spaced")

#numerical plotting
ax2.plot(np.sort(Xnums), Yvals)
ax2.set_xticks(np.sort(Xnums))
ax2.set_xticklabels(Xstr)
ax2.set_title("Numerical spacing")

plt.show()

示例输出: