Matplotlib在使用mpmath绘制时出现' TypeError '失败



我有2D数据,这是非常小的(顺序e-500),所以我不能使用numpy,我想画一个pcolormesh。例如,

import mpmath as mp
import matplotlib.pyplot as plt
import numpy as np
from mpmath import e as e
from mpmath import mpf, mpc,mp
mp.dps = 1000
y, x = np.meshgrid(np.linspace(-5, 5, 1000), np.linspace(-5, 5, 1000))
z = e ** (-x**2 + y)
z = z[:-1, :-1]
z_min, z_max = -np.abs(z).max(), np.abs(z).max()

编译得很好,但是当我想做pcolormesh时,事情就出错了:

fig, ax = plt.subplots()
c = ax.pcolormesh(x, y, z, cmap='RdBu', vmin=z_min, vmax=z_max)
ax.set_title('Titles are overall a positive feature')
ax.axis([x.min(), x.max(), y.min(), y.max()])
fig.colorbar(c, ax=ax)
plt.show()

给出错误TypeError: ufunc 'isnan' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''

为什么会发生这种情况?你知道怎么解决这个问题吗?也许没有mpmath的绘图会有帮助。

编辑:完整回溯

TypeError                                 Traceback (most recent call last)
~/.local/lib/python3.8/site-packages/IPython/core/formatters.py in __call__(self, obj)
339                 pass
340             else:
--> 341                 return printer(obj)
342             # Finally look for special method names
343             method = get_real_method(obj, self.print_method)
~/.local/lib/python3.8/site-packages/IPython/core/pylabtools.py in <lambda>(fig)
246 
247     if 'png' in formats:
--> 248         png_formatter.for_type(Figure, lambda fig: print_figure(fig, 'png', **kwargs))
249     if 'retina' in formats or 'png2x' in formats:
250         png_formatter.for_type(Figure, lambda fig: retina_figure(fig, **kwargs))
~/.local/lib/python3.8/site-packages/IPython/core/pylabtools.py in print_figure(fig, fmt, bbox_inches, **kwargs)
130         FigureCanvasBase(fig)
131 
--> 132     fig.canvas.print_figure(bytes_io, **kw)
133     data = bytes_io.getvalue()
134     if fmt == 'svg':
~/.local/lib/python3.8/site-packages/matplotlib/backend_bases.py in print_figure(self, filename, dpi, facecolor, edgecolor, orientation, format, bbox_inches, **kwargs)
2077                             print_method, dpi=dpi, orientation=orientation),
2078                         draw_disabled=True)
-> 2079                     self.figure.draw(renderer)
2080                     bbox_artists = kwargs.pop("bbox_extra_artists", None)
2081                     bbox_inches = self.figure.get_tightbbox(renderer,
~/.local/lib/python3.8/site-packages/matplotlib/artist.py in draw_wrapper(artist, renderer, *args, **kwargs)
36                 renderer.start_filter()
37 
---> 38             return draw(artist, renderer, *args, **kwargs)
39         finally:
40             if artist.get_agg_filter() is not None:
~/.local/lib/python3.8/site-packages/matplotlib/figure.py in draw(self, renderer)
1733 
1734             self.patch.draw(renderer)
-> 1735             mimage._draw_list_compositing_images(
1736                 renderer, self, artists, self.suppressComposite)
1737 
~/.local/lib/python3.8/site-packages/matplotlib/image.py in _draw_list_compositing_images(renderer, parent, artists, suppress_composite)
135     if not_composite or not has_images:
136         for a in artists:
--> 137             a.draw(renderer)
138     else:
139         # Composite any adjacent images together
~/.local/lib/python3.8/site-packages/matplotlib/artist.py in draw_wrapper(artist, renderer, *args, **kwargs)
36                 renderer.start_filter()
37 
---> 38             return draw(artist, renderer, *args, **kwargs)
39         finally:
40             if artist.get_agg_filter() is not None:
~/.local/lib/python3.8/site-packages/matplotlib/axes/_base.py in draw(self, renderer, inframe)
2628             renderer.stop_rasterizing()
2629 
-> 2630         mimage._draw_list_compositing_images(renderer, self, artists)
2631 
2632         renderer.close_group('axes')
~/.local/lib/python3.8/site-packages/matplotlib/image.py in _draw_list_compositing_images(renderer, parent, artists, suppress_composite)
135     if not_composite or not has_images:
136         for a in artists:
--> 137             a.draw(renderer)
138     else:
139         # Composite any adjacent images together
~/.local/lib/python3.8/site-packages/matplotlib/artist.py in draw_wrapper(artist, renderer, *args, **kwargs)
36                 renderer.start_filter()
37 
---> 38             return draw(artist, renderer, *args, **kwargs)
39         finally:
40             if artist.get_agg_filter() is not None:
~/.local/lib/python3.8/site-packages/matplotlib/collections.py in draw(self, renderer)
2045                 offsets = np.column_stack([xs, ys])
2046 
-> 2047         self.update_scalarmappable()
2048 
2049         if not transform.is_affine:
~/.local/lib/python3.8/site-packages/matplotlib/collections.py in update_scalarmappable(self)
790             return
791         if self._is_filled:
--> 792             self._facecolors = self.to_rgba(self._A, self._alpha)
793         elif self._is_stroked:
794             self._edgecolors = self.to_rgba(self._A, self._alpha)
~/.local/lib/python3.8/site-packages/matplotlib/cm.py in to_rgba(self, x, alpha, bytes, norm)
243         if norm:
244             x = self.norm(x)
--> 245         rgba = self.cmap(x, alpha=alpha, bytes=bytes)
246         return rgba
247 
~/.local/lib/python3.8/site-packages/matplotlib/colors.py in __call__(self, X, alpha, bytes)
559         if np.ma.is_masked(X):
560             mask_bad = X.mask
--> 561         elif np.any(np.isnan(X)):
562             # mask nan's
563             mask_bad = np.isnan(X)
TypeError: ufunc 'isnan' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''
<Figure size 432x288 with 2 Axes> ```

使用您的代码,编辑以在合理的测试时间内运行:

...: mp.dps = 10
...: y, x = np.meshgrid(np.linspace(-5, 5, 10), np.linspace(-5, 5, 10))
...: z = e ** (-x**2 + y)
...: z = z[:-1, :-1]
...: z_min, z_max = -np.abs(z).max(), np.abs(z).max()
...: 
In [11]: z
Out[11]: 
array([[mpf('9.357622969874e-14'), mpf('2.842594865759e-13'),
mpf('8.635040754285e-13'), mpf('2.623093769921e-12'),
mpf('7.968255300282e-12'), mpf('2.420542233701e-11'),
mpf('7.352958062098e-11'), mpf('2.233631436379e-10'),
mpf('6.785173193566e-10')],
...., dtype=object)
In [12]: z.dtype
Out[12]: dtype('O')
In [13]: np.isnan(z)
Traceback (most recent call last):
File "<ipython-input-13-72670087bbfa>", line 1, in <module>
np.isnan(z)
TypeError: ufunc 'isnan' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''

通过使用mpmath,您已经创建了一个对象类型数组。虽然这可能有更高的精度,但它也运行得更慢,在某些情况下根本不运行。

isnan期望一个数值dtype数组:

In [16]: np.any(np.isnan(z.astype(float)))
Out[16]: False

回溯显示plot使用isnan来"blank out"nan

如此:

plt.pcolormesh(x, y, z.astype('float128'), cmap='RdBu', vmin=z_min, vmax=z_max)

相关内容

最新更新