我有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)