Ошибка: _string_to_bool в mplot3d (обнаружено обходное решение)

Изменить: обходной путь в конце этого сообщения.

Я пытался запустить некоторые из приведенных примеров здесь и здесь.

Один из этих примеров:

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 

Я все еще получаю сообщение об ошибке, но по крайней мере получаю некоторый вывод.

Ответы

Ответ 1

Для меня (Ubuntu 14.04, используя систему Python) проблема была решена путем удаления apt-пакета python-matplotlib (вызвана этот отчет об ошибке). Более новый matplotlib также был установлен в /usr by pip; Я думаю, что некоторые более новые пакеты пакетов каким-то образом получили модули из старых apt-пакетов.

Это было после попытки выполнить команду meyerson pip install --upgrade --ignore-installed matplotlib[mplot3d], которая привела к перекомпиляции NumPy (и, я полагаю, Matplotlib была переустановлена), но не решила проблему.

Также интересно отметить, что я столкнулся с проблемой при запуске script (партии unittests) в командной строке, но не при запуске в тестовом бегуне LiClipse (который использует разные, явно изменяемые, PYTHONPATH. Я сожалею, что не пытался изменить этот порядок, чтобы увидеть, могу ли я воспроизвести проблему в Eclipse.

Ответ 2

У меня была точная проблема, вот как я ее решил (в моем случае):

1) переименуйте (или удалите) папку mplot3d (так что matplotlib думает, что ее нет):

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

2) обновите matplotlib с указанием mplot3d:

pip install --upgrade matplotlib[mplot3d]

Ответ 3

Добавление к обходному пути @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 из функции, и все работает отлично для меня, если я это сделал.

Ответ 4

Для меня ответ iamaziz не работает, и проблема возникает на Ubuntu 14.04 с использованием virtualenv с --system-site-packages и matplotlib, pandas, установленными через pip. Я обнаружил, что перемещение линии

 from mpl_toolkits.mplot3d import Axes3D

до импорта pandas решает проблему.

Ответ 5

Мне удалось получить работу в OS X 10.10.2, используя очень похожую обходную схему для тех, которые были размещены здесь. Ни один из конкретных обходных решений, опубликованных здесь, не работал в моем случае, но они помогли мне решить правильный вопрос. Все вещи mplot3d работали над моей линией Linux, а не на моем mac. Я использую homebrew на стороне OS X. Я получал ошибки в cbook, в частности ошибку _string_to_bool. Были вызовы, сделанные в cbook.py, axes3d.py и axes.py. Все, что я сделал для обходного пути, - это отслеживать файлы axes3d.py, axes.py и cbook.py в моем linux-окне и заменять эти файлы на моей машине 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/python 2.7): /usr/share/pyshared/matplotlib/axes.py

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

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

Просто создайте резервную копию, замените файлы из своего окна Linux и сделайте снимок, работая для меня.

Если у вас нет версии, запущенной в Linux, вы можете просто вытащить axes.py, axes3d.py и cbook.py из github, в котором есть файлы matplotlibs.py.

Ответ 6

В моем случае я импортировал морского и pandas вместе с Axes3D. Импортирование как морского и pandas после Axes3D удалило ошибку.