Pandas plot, vars() argument must have __dict__ attribute

回答 2 浏览 3930 2023-02-14

早些时候,它工作得很好,但由于某些原因,现在我得到了奇怪的错误。

pandas版本: 1.2.3

matplotlib版本:3.7.0

样本数据框架:

df
    cap       Date
0    1     2022-01-04
1    2     2022-01-06
2    3     2022-01-07
3    4     2022-01-08
df.plot(x='cap', y='Date')
plt.show()
df.dtypes
cap              int64
Date    datetime64[ns]
dtype: object

我得到的是一个追踪结果:

Traceback (most recent call last):
  File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/code.py", line 90, in runcode
    exec(code, self.locals)
  File "<input>", line 1, in <module>
  File "/Volumes/coding/venv/lib/python3.8/site-packages/pandas/plotting/_core.py", line 955, in __call__
    return plot_backend.plot(data, kind=kind, **kwargs)
  File "/Volumes/coding/venv/lib/python3.8/site-packages/pandas/plotting/_matplotlib/__init__.py", line 61, in plot
    plot_obj.generate()
  File "/Volumes/coding/venv/lib/python3.8/site-packages/pandas/plotting/_matplotlib/core.py", line 279, in generate
    self._setup_subplots()
  File "/Volumes/coding/venv/lib/python3.8/site-packages/pandas/plotting/_matplotlib/core.py", line 337, in _setup_subplots
    fig = self.plt.figure(figsize=self.figsize)
  File "/Volumes/coding/venv/lib/python3.8/site-packages/matplotlib/_api/deprecation.py", line 454, in wrapper
    return func(*args, **kwargs)
  File "/Volumes/coding/venv/lib/python3.8/site-packages/matplotlib/pyplot.py", line 813, in figure
    manager = new_figure_manager(
  File "/Volumes/coding/venv/lib/python3.8/site-packages/matplotlib/pyplot.py", line 382, in new_figure_manager
    _warn_if_gui_out_of_main_thread()
  File "/Volumes/coding/venv/lib/python3.8/site-packages/matplotlib/pyplot.py", line 360, in _warn_if_gui_out_of_main_thread
    if _get_required_interactive_framework(_get_backend_mod()):
  File "/Volumes/coding/venv/lib/python3.8/site-packages/matplotlib/pyplot.py", line 208, in _get_backend_mod
    switch_backend(rcParams._get("backend"))
  File "/Volumes/coding/venv/lib/python3.8/site-packages/matplotlib/pyplot.py", line 331, in switch_backend
    manager_pyplot_show = vars(manager_class).get("pyplot_show")
TypeError: vars() argument must have __dict__ attribute
Sid 提问于2023-02-14
这似乎是他们实现中的一个错误,他们假设manager_class有一个__dict__属性,但显然,它可能没有。这就是他们应该使用getattr(manager_class, "pyplot_show", None)而不是vars(manager_class).get("pyplot_show")juanpa.arrivillaga 2023-02-14
但是,由于你没有提供一个最小的可重复的例子,所以不可能说这是matplotlib的一个bug还是你做的事情。因为上面的代码如果我创建了合理的值和导入就能运行......请永远提供一个最小的可重复的例子juanpa.arrivillaga 2023-02-14
你使用的是最新的matplotlib和pandas版本吗?哪个matplotlib后端?哪种环境?JohanC 2023-02-14
我通过简单地调用plt.plot([1, 2, 3], [1, 2, 3])也遇到了同样的错误。tung 2023-02-15
在Python 3.9.5和matplotlib 3.7.0(jupyter环境之外)上,我也有同样的问题。不过在matplotlib==3.5.0上还可以。Ashkan Khademian 2023-02-17
2 个回答
#1楼 已采纳
得票数 12

事实上,如果你像默认脚本(或在PyCharm交互式控制台),而不是在Jupyter中运行你的代码,就可能会出现这个问题。

如果是真的,你可以通过在你的文件中直接用use函数设置后端来解决这个错误:

import matplotlib as mpl
import matplotlib.pyplot as plt

mpl.use('TkAgg')  # !IMPORTANT

fig, ax = plt.subplots()
res = ax.plot([1, 2, 3, 4], [1, 4, 2, 3])  # Plt some data on the axes.o
# plt.show() # optionally show the result.

在某些情况下,TkAgg可能无法使用。首先要检查,你使用的是哪一个后台。为此,运行这个简单的代码:

import matplotlib as mpl
print(mpl.get_backend())

但是!这必须在PyCharm之外,由你手动在默认终端中运行。(例如,创建简单的test.py文件,粘贴代码,然后运行python test.py)

为什么?因为PyCharm(至少在科学项目中)使用交互式控制台运行所有文件,其中使用了后端module://backend_interagg。而这个后端导致了和你一样的错误。

因此,在你的文件头部添加mpl.use('TkAgg'),或者查看你可以使用的后端,并将这些名称粘贴到这个函数中。

NEStenerus nester 提问于2023-02-15
#2楼
得票数 3

NEStenerus的解决方案对我不起作用,因为我没有安装tkinter,也不想改变我的包的配置。

另一种修复方法

相反,你可以禁用"show plots in tool window"选项,方法是进入Settings | Tools | Python Scientific | Show plots in tool window,然后取消勾选它。

johannesack 提问于2023-03-07