类似这样的代码(很抱歉代码有点长,大部分是从标准的axes.Axes.draw
复制过来的):
from operator import itemgetter
class generator_scatter_axes(matplotlib.axes.Axes):
def __init__(self, *args, **kwargs):
matplotlib.axes.Axes.__init__(self, *args, **kwargs)
self._big_data = None
def draw(self, renderer=None, inframe=None):
if renderer is None:
renderer = self._cachedRenderer
if renderer is None:
raise RuntimeError('No renderer defined')
if not self.get_visible():
return
renderer.open_group('axes')
locator = self.get_axes_locator()
if locator:
pos = locator(self, renderer)
self.apply_aspect(pos)
else:
self.apply_aspect()
artists = []
artists.extend(self.collections)
artists.extend(self.patches)
artists.extend(self.lines)
artists.extend(self.texts)
artists.extend(self.artists)
if self.axison and not inframe:
if self._axisbelow:
self.xaxis.set_zorder(0.5)
self.yaxis.set_zorder(0.5)
else:
self.xaxis.set_zorder(2.5)
self.yaxis.set_zorder(2.5)
artists.extend([self.xaxis, self.yaxis])
if not inframe:
artists.append(self.title)
artists.append(self._left_title)
artists.append(self._right_title)
artists.extend(self.tables)
if self.legend_ is not None:
artists.append(self.legend_)
if self.axison and self._frameon:
artists.extend(self.spines.itervalues())
if self.figure.canvas.is_saving():
dsu = [(a.zorder, a) for a in artists]
else:
dsu = [(a.zorder, a) for a in artists
if not a.get_animated()]
if len(self.images) <= 1 or renderer.option_image_nocomposite():
dsu.extend([(im.zorder, im) for im in self.images])
_do_composite = False
else:
_do_composite = True
dsu.sort(key=itemgetter(0))
rasterization_zorder = self._rasterization_zorder
if (rasterization_zorder is not None and
len(dsu) > 0 and dsu[0][0] < rasterization_zorder):
renderer.start_rasterizing()
dsu_rasterized = [l for l in dsu if l[0] < rasterization_zorder]
dsu = [l for l in dsu if l[0] >= rasterization_zorder]
else:
dsu_rasterized = []
if self.axison and self._frameon:
self.patch.draw(renderer)
if _do_composite:
zorder_images = [(im.zorder, im) for im in self.images
if im.get_visible()]
zorder_images.sort(key=lambda x: x[0])
mag = renderer.get_image_magnification()
ims = [(im.make_image(mag), 0, 0, im.get_alpha()) for z, im in zorder_images]
l, b, r, t = self.bbox.extents
width = mag * ((round(r) + 0.5) - (round(l) - 0.5))
height = mag * ((round(t) + 0.5) - (round(b) - 0.5))
im = mimage.from_images(height,
width,
ims)
im.is_grayscale = False
l, b, w, h = self.bbox.bounds
gc = renderer.new_gc()
gc.set_clip_rectangle(self.bbox)
gc.set_clip_path(mtransforms.TransformedPath(
self.patch.get_path(),
self.patch.get_transform()))
renderer.draw_image(gc, round(l), round(b), im)
gc.restore()
if dsu_rasterized:
for zorder, a in dsu_rasterized:
a.draw(renderer)
renderer.stop_rasterizing()
for zorder, a in dsu:
a.draw(renderer)
if self._big_data is not None:
for x, y, z in self._big_data:
a = self.scatter(x, y, color='r',
alpha=1, s=10, marker='s', linewidth=0)
a.draw(renderer)
a.remove()
del a
renderer.close_group('axes')
self._cachedRenderer = renderer
使用方法如下:
In [42]: fig = figure()
In [43]: ax = generator_scatter_axes(fig, [.1, .1, .8, .8])
In [44]: fig.add_axes(ax)
Out[44]: <__main__.generator_scatter_axes at 0x56fe090>
In [45]: ax._big_data = rand(500, 3)
In [46]: draw()
我将你的散点函数更改为在小数量下可见的形状。由于您每次都在设置一个
scatter
对象,因此这将非常慢。我建议您要么采取合理的数据块并绘制它们,要么替换对
scatter
的调用以使用底层的艺术家对象,或者使用Joe的建议仅更新单个艺术家。
Axes
子类,覆盖draw
函数并为每个点生成一个艺术家,将其光栅化和合成,然后在制作下一个之前丢弃艺术家。 - tacaswell_internal_data = np.array(input_data)
的道德等价物,如果你正在进行颜色映射,那么散点对象最终将至少占用 6N64 B(N 行,6 或 7 个浮点数(XYZ、RGB(可能是 A)、64 位))。 - tacaswellmatplotlib.axes.Axes.draw
的代码。 - tacaswell