【问题标题】:Plot graph with vertical labels on the x-axis Matplotlib在 x 轴 Matplotlib 上绘制带有垂直标签的图形
【发布时间】:2021-06-03 15:03:54
【问题描述】:

为了继续研究如何绘制 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 是否可以将标签转换为数字,然后在图形旁边的标签旁边绘制数字的描述,以使图形更易于理解?

【问题讨论】:

  • df _ Signals? Split('')?请将语法和空间问题修复为可编译代码。

标签: python matplotlib axis-labels


【解决方案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

【讨论】:

    【解决方案2】:

    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.plotx 参数:

    (signals_df[signals_df["Name"].isin(names_list)]
        .plot(kind="line", x="Name", rot=0)
    )
    

    但是,如果Name 在数据中重复多次,set_index 可能会引发错误,并且x 参数可能会返回不希望的结果。因此,就像您之前的帖子一样,请考虑运行 groupby 来汇总每个唯一 NameValue。低于每个名称的平均值:

    signals_df.groupby(["Name"])["Value"].mean().plot(kind="line", rot=0)
    

    【讨论】:

    • 非常感谢@Parfait,这是帮助我的答案。是否有任何方式、方法或绘图属性可以让所有名称标签出现在图表上?而不是图像中显示的那样:link