错误:mplot3d中的_string_to_bool(已找到解决方法)

17

编辑:此帖末尾提供解决方法。

我试图运行一些在这里这里提供的示例。

其中一个示例是:

from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import numpy as np

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

u = np.linspace(0, 2 * np.pi, 100)
v = np.linspace(0, np.pi, 100)

x = 10 * np.outer(np.cos(u), np.sin(v))
y = 10 * np.outer(np.sin(u), np.sin(v))
z = 10 * np.outer(np.ones(np.size(u)), np.cos(v))
ax.plot_surface(x, y, z,  rstride=4, cstride=4, color='b')

plt.show()

这给了我以下错误:

/usr/lib/pymodules/python2.7/mpl_toolkits/mplot3d/axes3d.py:842: MatplotlibDeprecationWarning: The set_scale function was deprecated in version 1.3.
  self.zaxis.set_scale('linear')
Traceback (most recent call last):
  File "/mnt/hgfs/MCLS/postprocessing/surface3d_demo2.py", line 6, in <module>
    ax = fig.add_subplot(111, projection='3d')
  File "/usr/local/lib/python2.7/dist-packages/matplotlib-1.4.x-py2.7-linux-x86_64.egg/matplotlib/figure.py", line 958, in add_subplot
    a = subplot_class_factory(projection_class)(self, *args, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/matplotlib-1.4.x-py2.7-linux-x86_64.egg/matplotlib/axes/_subplots.py", line 78, in __init__
    self._axes_class.__init__(self, fig, self.figbox, **kwargs)
  File "/usr/lib/pymodules/python2.7/mpl_toolkits/mplot3d/axes3d.py", line 78, in __init__
    *args, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/matplotlib-1.4.x-py2.7-linux-x86_64.egg/matplotlib/axes/_base.py", line 436, in __init__
    self.cla()
  File "/usr/lib/pymodules/python2.7/mpl_toolkits/mplot3d/axes3d.py", line 847, in cla
    Axes.cla(self)
  File "/usr/local/lib/python2.7/dist-packages/matplotlib-1.4.x-py2.7-linux-x86_64.egg/matplotlib/axes/_base.py", line 897, in cla
    self.grid(self._gridOn, which=rcParams['axes.grid.which'])
  File "/usr/lib/pymodules/python2.7/mpl_toolkits/mplot3d/axes3d.py", line 1057, in grid
    self._draw_grid = maxes._string_to_bool(b)
AttributeError: 'module' object has no attribute '_string_to_bool'

错误产生于: ax = fig.add_subplot(111, projection='3d')

我尝试检查和升级matplotlib。运行python -c 'import matplotlib; print matplotlib.__version__'的结果是1.4.x

我深入研究了底层代码,发现了这个问题:

def grid(self, b=True, **kwargs):
'''
Set / unset 3D grid.

.. note::
    Currently, this function does not behave the same as
    :meth:`matplotlib.axes.Axes.grid`, but it is intended to
    eventually support that behavior.

.. versionchanged :: 1.1.0
    This function was changed, but not tested. Please report any bugs.
'''
# TODO: Operate on each axes separately
if len(kwargs) :
    b = True
self._draw_grid = maxes._string_to_bool(b)

有人可以给我一个建议去哪里继续吗?

编辑: 我已经找到了解决这个问题的方法。正如最后一个错误信息所示,_string_to_bool函数出了一些问题。只需要添加以下一行即可:

from matplotlib.cbook import _string_to_bool

在...之上

/usr/lib/pymodules/python2.7/mpl_toolkits/mplot3d/axes3d.py 

我仍然收到错误信息,但至少我能得到一些输出。


你是如何安装mpl的?看起来你正在从/usr/lib内部获取文件,而在大多数系统上,这是由操作系统包管理器控制的,但我不知道有谁会发布1.4.x版本。 - tacaswell
https://github.com/matplotlib/matplotlib/blob/master/lib/mpl_toolkits/mplot3d/axes3d.py#L1262 是 axes3d.py 中使用该函数的唯一位置,且最后一次修改是在2013年。我怀疑实际问题是您安装的出了问题。 - tacaswell
1
@tcaswell 我忘记了我以前如何安装mpl。现在我使用sudo apt-get install python-mpltoolkits.basemap重新安装了mpl_toolkit。在使用sudo apt-get purge --auto-remove python-mpltoolkits.basemap并手动删除mpl_toolkits文件夹之后,这个新的安装没有出现任何问题。感谢你的帮助! - Hennep
6个回答

11

对于我来说(在Ubuntu 14.04上,使用系统Python),问题是通过删除apt包python-matplotlib解决的(因为这个bug报告提示了)。新版matplotlib也通过pip安装在了/usr下;我认为一些更新的pip包会以某种方式从旧的apt包中获取模块。

在尝试meyerson的pip install --upgrade --ignore-installed matplotlib[mplot3d]命令后,问题并未得到解决。虽然这个命令导致了NumPy的重新编译(我想这个结果就是Matplotlib被重新安装了),但并没有解决问题。

有趣的是,我只有在命令行运行相应的脚本(一批unittests)时才遇到了这个问题,但在LiClipse测试运行器中运行时却没有(它使用不同的、可以明确更改的PYTHONPATH顺序)。我很遗憾没有尝试更改这个顺序,看看能否在Eclipse中重现这个问题。


sudo apt-get remove python-matplotlib 对我来说也解决了这个问题。 - niekas
3
这对我也起作用。我之前安装了python-matplotlib,留下了一些文件,新版本引用了这些文件。在错误报告线程中的一篇文章揭示了我的情况以及可能大部分或所有其他遇到此问题的人的问题:在旧版本中,工具包存储在单独的mpl_toolkits文件夹中,现在已移动到matplotlib文件夹中。因此,在安装新版本的matplotlib时不会覆盖此版本,并且在导入工具包时错误地引用了旧版本的工具包。 - toes

8

我遇到了同样的问题,以下是我的解决方法(根据我的情况):

1)重命名(或删除)文件夹mplot3d(这样matplotlib就会认为它不在那里):

/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/mpl_toolkits/mplot3d-old

2) 使用指定的mplot3d更新matplotlib

pip install --upgrade matplotlib[mplot3d]

1
实际上,对我来说第一步是必要的 - 似乎只需要在覆盖系统环境的虚拟环境中添加额外的mplot3d需求即可。工作得非常好 :) - metakermit
2
我认为强制安装/升级+忽略已安装的操作等同于这个解决方案。pip install --upgrade --ignore-installed matplotlib[mplot3d] - meyerson
对我没用。我在Ubuntu上使用python虚拟环境,并使用--system-site-packages(以便其他带有二进制文件的软件包能够正确工作)。 - Valentas
1
对我没有用。UnknownExtra: matplotlib 1.4.3没有'mplot3d'这个额外功能 - moonkey
@metakermit 是的,我也遇到了同样的问题,更改过时文件夹的名称可以解决这个问题。实际上,我通过pip将我的matplotlib升级到1.5版本,似乎Python对路径感到困惑。 - lenhhoxung

3

对于我来说,iamaziz的回答没有起作用,这个问题出现在使用virtualenv和pip安装matplotlib、pandas的情况下,系统是Ubuntu 14.04,并加上了--system-site-packages选项。我发现移动以下这行代码可以解决此问题:

 from mpl_toolkits.mplot3d import Axes3D

在导入pandas之前解决问题。

这对我来说是最简单的解决方法,而且运行得非常顺畅。谢谢。 - Gaurav Jain

2

在 @Hennep 的解决方法上添加:

将以下行添加到文件中

/usr/lib/pymodules/python2.7/mpl_toolkits/mplot3d/axes3d.py

from matplotlib.cbook import _string_to_bool

然后更改代码为

def grid(self, b=True, **kwargs):
'''Set / unset 3D grid.

.. note::
Currently, this function does not behave the same as
:meth:`matplotlib.axes.Axes.grid`, but it is intended to
eventually support that behavior.

.. versionchanged :: 1.1.0
This function was changed, but not tested. Please report any bugs.
'''
# TODO: Operate on each axes separately
if len(kwargs) :
    b = True
self._draw_grid = _string_to_bool(b)

如果我这样做,从函数中删除单词maxes,那么一切都可以正常工作。


1
在我的情况下,我导入了 seabornpandas 以及 Axes3D。在导入 Axes3D 后再导入 seabornpandas 可以消除错误。

1
我成功地使用了一个非常类似于这里发布的解决方法在OS X 10.10.2上实现了工作。这里发布的具体解决方法都没有在我的情况下奏效,但是他们让我找到了解决问题的正确方向。所有的mplot3d内容都在我的linux框架上运行正常,但在我的mac上却不行。我在OS X系统上使用homebrew。我在cbook中遇到了错误,特别是_string_to_bool错误。cbook.py、axes3d.py和axes.py中都有调用。我所做的所有解决方法就是在我的linux框架上找到axes3d.py、axes.py和cbook.py文件,并将这些文件替换为我的OS X机器上的文件,之后一切都完美地工作了,我能够使用mplot3。Homebrew使用了很多符号链接,因此请注意这一点,我喜欢备份原始文件并将它们替换在那里,而不是在链接级别。Brew也可能会将文件分散到不同的位置,在我的机器上它们位于以下位置:

/Library/Python/2.7/site-packages/matplotlib-override/matplotlib/axes.py

/usr/local/Cellar/matplotlib/1.4.2/lib/python2.7/site-packages/mpl_toolkits/mplot3d/axes3d.py

/usr/local/Cellar/matplotlib/1.4.2/lib/python2.7/site-packages/matplotlib/cbook.py

在Linux端(从/usr/lib/pymodules/python2.7软链接过来): /usr/share/pyshared/matplotlib/axes.py

/usr/share/pyshared/matplotlib/cbook.py

/usr/share/pyshared/mpl_toolkits/mplot3d/axes3d.py

只需备份,将来自您的Linux框中的文件替换掉,然后尝试一下,这对我有效。

如果您没有在Linux上运行版本,则可以从GitHub获取axes.py、axes3d.py和cbook.py,其中发布了matplotlib的.py文件。


格式化您的答案以提高其可读性。 - ryanyuyu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接