diff --git a/lib/matplotlib/backends/backend_webagg_core.py b/lib/matplotlib/backends/backend_webagg_core.py index e75014b1e632..4d7c942f17f2 100644 --- a/lib/matplotlib/backends/backend_webagg_core.py +++ b/lib/matplotlib/backends/backend_webagg_core.py @@ -121,7 +121,7 @@ def _handle_key(key): class FigureCanvasWebAggCore(backend_agg.FigureCanvasAgg): - supports_blit = False + supports_blit = True def __init__(self, *args, **kwargs): backend_agg.FigureCanvasAgg.__init__(self, *args, **kwargs) @@ -162,9 +162,17 @@ def draw(self): # Swap the frames self.manager.refresh_all() + def blit(self, bbox=None): + self._png_is_old = True + self.manager.refresh_all() + def draw_idle(self): self.send_event("draw") + def copy_from_bbox(self, bbox): + renderer = self._last_renderer + return renderer.copy_from_bbox(bbox) + def set_image_mode(self, mode): """ Set the image mode for any subsequent images which will be sent @@ -215,6 +223,11 @@ def get_diff_image(self): # Swap the renderer frames self._renderer, self._last_renderer = ( self._last_renderer, renderer) + + self.figure._cachedRenderer = self._renderer + for ax in self.figure.axes: + ax._cachedRenderer = self._renderer + self._force_full = False self._png_is_old = False return buff diff --git a/lib/matplotlib/backends/web_backend/nbagg_uat.ipynb b/lib/matplotlib/backends/web_backend/nbagg_uat.ipynb index dfb264c37591..c2662722e995 100644 --- a/lib/matplotlib/backends/web_backend/nbagg_uat.ipynb +++ b/lib/matplotlib/backends/web_backend/nbagg_uat.ipynb @@ -3,9 +3,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "from __future__ import print_function\n", @@ -24,12 +22,11 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "import matplotlib\n", + "\n", "reload(matplotlib)\n", "\n", "matplotlib.use('nbagg')\n", @@ -50,16 +47,14 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "import matplotlib.backends.backend_webagg_core\n", "reload(matplotlib.backends.backend_webagg_core)\n", "\n", "import matplotlib.pyplot as plt\n", - "plt.interactive(False)\n", + "plt.interactive(True)\n", "\n", "fig1 = plt.figure()\n", "plt.plot(range(10))\n", @@ -79,9 +74,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "plt.plot([3, 2, 1])\n", @@ -100,9 +93,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "print(matplotlib.backends.backend_nbagg.connection_info())" @@ -120,9 +111,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "plt.close(fig1)" @@ -141,9 +130,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "plt.plot(range(10))" @@ -161,9 +148,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "print(matplotlib.backends.backend_nbagg.connection_info())" @@ -181,9 +166,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "plt.show()\n", @@ -204,9 +187,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "plt.interactive(True)\n", @@ -224,9 +205,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "plt.plot(range(3))" @@ -242,9 +221,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "print(matplotlib.backends.backend_nbagg.connection_info())" @@ -260,9 +237,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "plt.interactive(False)" @@ -280,9 +255,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "plt.gcf().canvas.manager.reshow()" @@ -311,9 +284,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "fig = plt.figure()\n", @@ -336,9 +307,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "from matplotlib.backends.backend_nbagg import new_figure_manager,show\n", @@ -362,9 +331,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "import matplotlib.animation as animation\n", @@ -405,9 +372,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "import matplotlib\n", @@ -431,9 +396,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "import itertools\n", @@ -478,9 +441,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "import time\n", @@ -507,9 +468,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "fig, ax = plt.subplots()\n", @@ -532,9 +491,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "fig, ax = plt.subplots()\n", @@ -550,9 +507,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "fig, ax = plt.subplots()\n", @@ -570,7 +525,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### UAT17 - stopping figure when removed from DOM\n", + "### UAT18 - stopping figure when removed from DOM\n", "\n", "When the div that contains from the figure is removed from the DOM the figure should shut down it's comm, and if the python-side figure has no more active comms, it should destroy the figure. Repeatedly running the cell below should always have the same figure number" ] @@ -578,9 +533,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "fig, ax = plt.subplots()\n", @@ -598,29 +551,70 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "fig.canvas.manager.reshow()" ] }, { - "cell_type": "code", - "execution_count": null, + "cell_type": "markdown", "metadata": { "collapsed": true }, + "source": [ + "### UAT 17 - Blitting\n", + "\n", + "\n", + "Clicking on the figure should plot a green horizontal line moving up the axes.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import itertools\n", + "\n", + "cnt = itertools.count()\n", + "bg = None\n", + "\n", + "def onclick_handle(event):\n", + " \"\"\"Should draw elevating green line on each mouse click\"\"\"\n", + " global bg\n", + " if bg is None:\n", + " bg = ax.figure.canvas.copy_from_bbox(ax.bbox) \n", + " ax.figure.canvas.restore_region(bg)\n", + "\n", + " cur_y = (next(cnt) % 10) * 0.1\n", + " ln.set_ydata([cur_y, cur_y])\n", + " ax.draw_artist(ln)\n", + " ax.figure.canvas.blit(ax.bbox)\n", + "\n", + "\n", + "fig, ax = plt.subplots()\n", + "ax.plot([0, 1], [0, 1], 'r')\n", + "ln, = ax.plot([0, 1], [0, 0], 'g', animated=True)\n", + "plt.show()\n", + "ax.figure.canvas.draw()\n", + "\n", + "ax.figure.canvas.mpl_connect('button_press_event', onclick_handle)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { - "display_name": "Python 3", + "display_name": "dd36", "language": "python", - "name": "python3" + "name": "myenv" }, "language_info": { "codemirror_mode": { @@ -632,9 +626,9 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.4.3" + "version": "3.6.4" } }, "nbformat": 4, - "nbformat_minor": 0 + "nbformat_minor": 1 }