为了继续研究如何绘制xml文件并继续检查我的代码,我首先对signal.attrib ["Value"]
应用了除法,因为它显示了一些字符串值,而我感兴趣的是数字价值。
正如您在下面看到的,我依赖于 Pandas and SQL Compare 的文档。
import xml.etree.ElementTree as ET
import pandas as pd
from matplotlib import pyplot as plot
def transformData (rootXML):
print ("File:", rootXML)
file_xml = ET.parse (rootXML)
data_XML = [
{"Name": signal.attrib ["Name"],
# "Value": signal.attrib ["Value"]
"Value": int (signal.attrib ["Value"].split(' ')[0])
} for the signal in file_xml.findall (".//Signal")
]
signals_df = pd.DataFrame (XML_data)
signals_df [(signals_df ["Name"] == 'Status') |
(signals_df ["Name"] == 'Lock_Stat')]. plot (kind = 'line', rot = 0)
plot.title ('Changing signals every time they occur')
plot.xlabel ('Signal name')
plot.ylabel ('Signal value')
plot.show ()
plot.clf ()
plot.close ()
我用一个完整的 xml 文件运行它,其中包含很多信号,例如在 this link 中找到的那个:(我把它放在这里是因为由于 xml 的长度,它不允许我附加代码)
所以,一旦我编译了所有数据,我就运行了图表,结果是这样的(并非所有标签都在文件中):
实际上我必须使用的是类似于 this page 底部附近的“开关点跟踪”图。但现在我正在研究它,它以线图形式为我服务。
但是如何在 x 轴上除以标签名称(“名称”)而不是数字 0、20、40 等,即如何使所有名称都出现在图形上和把它们垂直放置?是否有可能做到这一点?或者我不知道... Matplotlib 可以将标签转换为数字,然后在图表旁边的标签旁边绘制数字的描述,使图表更易于理解吗?
答案 0 :(得分:1)
是的,你可以,使用 xticks()。
# Your labels list
labels = [chr(x) for x in range(65, 91)]
# > ["A", "B", "C" ..., "Z"] as an example
import numpy as np
data = np.random.rand(26, 1) # random data to illustrate
import matplotlib.pyplot as plt
plt.xticks(ticks=range(len(data)), labels=labels, rotation=90)
plt.plot(data) # Your data
plt.show()
请注意,大多数情况下,当您想对情节进行更精彩的处理时,您需要更精确地操作图形和斧头,并使用更多可用参数。
fig, ax = plt.subplots()
ax.set_xticks(range(len(data)))
ax.set_xticklabels(labels, rotation=90)
ax.plot(data)
plt.show()
# Same result
答案 1 :(得分:0)
pandas 中的线图默认使用 DataFrame 或 Series 索引。考虑在绘图之前将索引设置为 Name
。此外,使用 Series.isin
进行需要的多个值过滤:
names_list = [
'Status', 'SetDSP', 'HMI', 'Delay', 'AutoConfigO_Rear', 'AutoConfigO_Front',
'AutoConfigO_Drvr', 'AutoConfigO_Allst', 'RUResReqstStat', 'RUReqstrSystem',
'RUSource', 'DSP', 'CurrTUBand', 'DrStatDrv', 'PW_Chim', 'BtnID', 'Cod_BtnID',
'SetVol', 'Lock_Stat'
]
(signals_df[signals_df["Name"].isin(names_list)]
.set_index("Name")
.plot(kind="line", rot=0)
)
或使用DataFrame.query
:
(signals_df.query("Name == @names_list")
.set_index("Name")
.plot(kind="line", rot=0)
)
或者,使用 pandas.DataFrame.plot
的 x
参数:
(signals_df[signals_df["Name"].isin(names_list)]
.plot(kind="line", x="Name", rot=0)
)
但是,如果 set_index
在数据中重复多次,x
可能会引发错误并且 Name
参数可能会返回不需要的结果。因此,与您之前的博文一样,请考虑运行 groupby
来汇总每个唯一 Name 的 Value。低于每个名称的平均值:
signals_df.groupby(["Name"])["Value"].mean().plot(kind="line", rot=0)