【问题标题】:matplotlib error when using split list entry as argument使用拆分列表条目作为参数时出现 matplotlib 错误
【发布时间】:2021-03-23 03:30:17
【问题描述】:

我想在 matplotlib 中使用由外观命令组成的列表条目,以便于编辑线条颜色和类型。但是当我运行以下代码时,出现 2 个错误:

  1. '类型对象有多个关键字参数'ax'的值'
Traceback (most recent call last):
  File "./plotMeltFront.py", line 34, in <module>
    data.plot(0, 1, ax=ax1, label=myLabel, *sets[i][2].split())
  File "/home/ksalscheider/.local/lib/python3.6/site-packages/pandas/plotting/_core.py", line 872, in __call__
    plot_backend.__name__, self._parent, args, kwargs
  File "/home/ksalscheider/.local/lib/python3.6/site-packages/pandas/plotting/_core.py", line 859, in _get_call_args
    kwargs = dict(arg_def, **pos_args, **kwargs)
TypeError: type object got multiple values for keyword argument 'ax'
  1. 删除 ax 参数时,错误提示“color="C0" 不是有效的绘图类型”
Traceback (most recent call last):
  File "./plotMeltFront.py", line 34, in <module>
    data.plot(0, 1, label=myLabel, *sets[i][2].split())
  File "/home/ksalscheider/.local/lib/python3.6/site-packages/pandas/plotting/_core.py", line 882, in __call__
    raise ValueError(f"{kind} is not a valid plot kind")
ValueError: color="C0" is not a valid plot kind

两个我都不懂。对于 1 我没有在列表中声明第二个 ax 值,为什么这样说?编写data.plot(0, 1, label=myLabel, 'color="C0"') 时也会出现错误2(注意' 周围的颜色)。这模仿了列表条目的外观,在打印列表时。有没有办法从拆分列表条目中删除 '?

我在链接 python script with example data 中包含了带有一些示例集的脚本

#!/usr/bin/python3

import os
import matplotlib.pyplot as plt
import pandas as pd

sets = []
iOld = -1

#--------USER EDIT--------#

#["set directory name", "label", 'set appearence']
sets.append(["set1", "Experiment", 'color="C0" linestyle=":"'])
sets.append(["set2", "Linear", 'color="C1" linestyle="--"'])
sets.append(["set3", "Erf", 'color="C2" linestyle="-."'])

print(sets[0][2].split())

#------USER EDIT END------'

fig = plt.figure()
ax1 = fig.add_subplot()

for i in range(len(sets)):
    for j in os.listdir(sets[i][0]):
        filepath = os.path.abspath(sets[i][0]) + "/" + j
        data = pd.read_csv(filepath, delimiter=',', engine='python',
               header=None, skipfooter=1, error_bad_lines=False)
        if i != iOld:
            myLabel = sets[i][1];
        else:
            myLabel = '_nolegend_'

        data.plot(0, 1, ax=ax1, label=myLabel, *sets[i][2].split())
        iOld = i

plt.show()

PS:“nolegend”条目会抛出很多警告,有没有办法禁用它们?

【问题讨论】:

标签: python list matplotlib arguments


【解决方案1】:

要为函数提供额外参数,您不能使用拆分字符串。在问题示例中,拆分字符串将显示为:

# data.plot(0, 1, ax=ax1, label=myLabel, *sets[i][2].split())
data.plot(0, 1, ax=ax1, label=myLabel, 'color="C0"', 'linestyle=":"')

这不是有效的 Python 代码。 Python 不会将其解释为parametername=value,而只是将其解释为字符串。当 pandas 对参数进行一些重新排列时,会生成一条相当无用的错误消息(似乎将其解释为 ax='color="C0"')。

要走的路是将这些值存储在字典中,该字典可以通过** 转换为parameter=value 对:

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd

sets = []
sets.append(["set1", "Experiment", {"color": "C0", "linestyle": ":"}])
sets.append(["set2", "Linear", {"color": "C1", "linestyle": "--"}])
sets.append(["set3", "Erf", {"color": "C2", "linestyle": "-."}])

fig = plt.figure()
ax1 = fig.add_subplot()

iOld = None
for i in range(len(sets)):
    for j in range(2):
        data = pd.DataFrame({'x': np.arange(100), 'y': np.random.randn(100).cumsum()})
        myLabel = sets[i][1] if i != iOld else '_nolegend_'
        legend_dict = {'legend': i != iOld}
        data.plot(0, 1, ax=ax1, label=myLabel, **sets[i][2], **legend_dict)
        iOld = i
plt.show()

关于 _nolegend_ 的恼人警告是 pandas 如何调用 matplotlib 图例函数的结果。在这种情况下,一种方法是为图例中不应出现的图添加legend=False

【讨论】:

  • 非常感谢您的回复,效果很好,但在我的情况下图例不正确 :( 当我运行您的脚本时,图例中的前 2 个条目是相同的颜色和破折号模式,第三个正确显示。当我加载我的文件时,即使线条显示正确,图例也会显示同一庄园中的所有集合。这发生在 python 3 和 3.8 上的 matplotlib 版本 3.3.3 上。任何想法这个?
  • 我升级了我的库,并注意到了同样的问题。将代码更新为myLabel = sets[i][1] if i != iOld else '_nolegend_'(并维护legend=False 以抑制警告)似乎可以解决问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-01-14
  • 2017-02-21
  • 2017-07-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多