From 878978664d4bd0cce1e45c7319073399d2c7e66a Mon Sep 17 00:00:00 2001 From: Henrik Schmidt Date: Fri, 4 Sep 2020 18:39:57 +0200 Subject: [PATCH] Fixes issue #69 Visual Studio Code does not render progress bars correctly --- fastprogress/_nbdev.py | 1 + fastprogress/fastprogress.py | 29 +++-- nbs/01_fastprogress.ipynb | 233 +++++++++++++++++++---------------- 3 files changed, 149 insertions(+), 114 deletions(-) diff --git a/fastprogress/_nbdev.py b/fastprogress/_nbdev.py index fc806f6..cb2c968 100644 --- a/fastprogress/_nbdev.py +++ b/fastprogress/_nbdev.py @@ -11,6 +11,7 @@ "IN_NOTEBOOK": "00_core.ipynb", "ProgressBar": "01_fastprogress.ipynb", "MasterBar": "01_fastprogress.ipynb", + "NBOutput": "01_fastprogress.ipynb", "NBProgressBar": "01_fastprogress.ipynb", "NBMasterBar": "01_fastprogress.ipynb", "NO_BAR": "01_fastprogress.ipynb", diff --git a/fastprogress/fastprogress.py b/fastprogress/fastprogress.py index ffce451..39a9a35 100644 --- a/fastprogress/fastprogress.py +++ b/fastprogress/fastprogress.py @@ -1,8 +1,9 @@ # AUTOGENERATED! DO NOT EDIT! File to edit: nbs/01_fastprogress.ipynb (unless otherwise specified). -__all__ = ['ProgressBar', 'MasterBar', 'NBProgressBar', 'NBMasterBar', 'NO_BAR', 'WRITER_FN', 'FLUSH', 'SAVE_PATH', - 'SAVE_APPEND', 'MAX_COLS', 'printing', 'ConsoleProgressBar', 'print_and_maybe_save', 'ConsoleMasterBar', - 'master_bar', 'progress_bar', 'force_console_behavior', 'workaround_empty_console_output'] +__all__ = ['ProgressBar', 'MasterBar', 'NBOutput', 'NBProgressBar', 'NBMasterBar', 'NO_BAR', 'WRITER_FN', 'FLUSH', + 'SAVE_PATH', 'SAVE_APPEND', 'MAX_COLS', 'printing', 'ConsoleProgressBar', 'print_and_maybe_save', + 'ConsoleMasterBar', 'master_bar', 'progress_bar', 'force_console_behavior', + 'workaround_empty_console_output'] # Cell import time,os,shutil @@ -98,16 +99,30 @@ def update(self, val): self.main_bar.update(val) try: from IPython.display import clear_output, display, HTML import matplotlib.pyplot as plt + import ipywidgets as widgets except: warn("Couldn't import ipywidgets properly, progress bar will use console behavior") IN_NOTEBOOK = False +# Cell +class NBOutput(): + def __init__(self, to_display): + self.out = widgets.Output() + display(self.out) + with self.out: + display(to_display) + + def update(self, to_update): + with self.out: + clear_output(wait=True) + display(to_update) + # Cell class NBProgressBar(ProgressBar): def on_iter_begin(self): super().on_iter_begin() self.progress = html_progress_bar(0, self.total, "") - if self.display: self.out = display(HTML(self.progress), display_id=True) + if self.display: self.out = NBOutput(HTML(self.progress)) self.is_active=True def on_interrupt(self): @@ -138,7 +153,7 @@ def __init__(self, gen, total=None, hide_graph=False, order=None, clean_on_inter def on_iter_begin(self): self.html_code = '\n'.join([html_progress_bar(0, self.main_bar.total, ""), ""]) - self.out = display(HTML(self.html_code), display_id=True) + self.out = NBOutput(HTML(self.html_code)) def on_interrupt(self): if self.clean_on_interrupt: self.out.update(HTML('')) @@ -182,14 +197,14 @@ def show_imgs(self, imgs, titles=None, cols=4, imgsize=4, figsize=None): if titles is None: titles = [None] * len(imgs) for img, ax, title in zip(imgs, imgs_axs.flatten(), titles): img.show(ax=ax, title=title) for ax in imgs_axs.flatten()[len(imgs):]: ax.axis('off') - if not hasattr(self, 'imgs_out'): self.imgs_out = display(self.imgs_fig, display_id=True) + if not hasattr(self, 'imgs_out'): self.imgs_out = NBOutput(self.imgs_fig) else: self.imgs_out.update(self.imgs_fig) def update_graph(self, graphs, x_bounds=None, y_bounds=None, figsize=(6,4)): if self.hide_graph: return if not hasattr(self, 'graph_fig'): self.graph_fig, self.graph_ax = plt.subplots(1, figsize=figsize) - self.graph_out = display(self.graph_ax.figure, display_id=True) + self.graph_out = NBOutput(self.graph_ax.figure) self.graph_ax.clear() if len(self.names) < len(graphs): self.names += [''] * (len(graphs) - len(self.names)) for g,n in zip(graphs,self.names): self.graph_ax.plot(*g, label=n) diff --git a/nbs/01_fastprogress.ipynb b/nbs/01_fastprogress.ipynb index 3e4d8b0..c255d44 100644 --- a/nbs/01_fastprogress.ipynb +++ b/nbs/01_fastprogress.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "metadata": {}, "outputs": [], "source": [ @@ -15,7 +15,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "metadata": {}, "outputs": [], "source": [ @@ -31,7 +31,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "metadata": {}, "outputs": [], "source": [ @@ -103,7 +103,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, "metadata": {}, "outputs": [], "source": [ @@ -116,7 +116,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 5, "metadata": {}, "outputs": [], "source": [ @@ -126,7 +126,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 6, "metadata": {}, "outputs": [], "source": [ @@ -140,7 +140,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 7, "metadata": {}, "outputs": [], "source": [ @@ -156,7 +156,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 8, "metadata": {}, "outputs": [], "source": [ @@ -181,7 +181,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 9, "metadata": {}, "outputs": [], "source": [ @@ -195,8 +195,10 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, + "execution_count": 10, + "metadata": { + "tags": [] + }, "outputs": [ { "name": "stdout", @@ -223,7 +225,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 11, "metadata": {}, "outputs": [], "source": [ @@ -241,7 +243,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 12, "metadata": {}, "outputs": [], "source": [ @@ -250,6 +252,7 @@ " try:\n", " from IPython.display import clear_output, display, HTML\n", " import matplotlib.pyplot as plt\n", + " import ipywidgets as widgets\n", " except:\n", " warn(\"Couldn't import ipywidgets properly, progress bar will use console behavior\")\n", " IN_NOTEBOOK = False" @@ -257,7 +260,27 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 13, + "metadata": {}, + "outputs": [], + "source": [ + "#export\n", + "class NBOutput():\n", + " def __init__(self, to_display):\n", + " self.out = widgets.Output()\n", + " display(self.out)\n", + " with self.out:\n", + " display(to_display)\n", + "\n", + " def update(self, to_update):\n", + " with self.out:\n", + " clear_output(wait=True)\n", + " display(to_update)" + ] + }, + { + "cell_type": "code", + "execution_count": 14, "metadata": {}, "outputs": [], "source": [ @@ -266,7 +289,7 @@ " def on_iter_begin(self):\n", " super().on_iter_begin()\n", " self.progress = html_progress_bar(0, self.total, \"\")\n", - " if self.display: self.out = display(HTML(self.progress), display_id=True)\n", + " if self.display: self.out = NBOutput(HTML(self.progress))\n", " self.is_active=True\n", "\n", " def on_interrupt(self):\n", @@ -287,33 +310,18 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 15, "metadata": {}, "outputs": [ { "data": { - "text/html": [ - "\n", - "
\n", - " \n", - " \n", - " 100.00% [100/100 00:05<00:00]\n", - "
\n", - " " - ], + "application/vnd.jupyter.widget-view+json": { + "model_id": "3c9f610f4ea1427cb87e0bee71b3a491", + "version_major": 2, + "version_minor": 0 + }, "text/plain": [ - "" + "Output()" ] }, "metadata": {}, @@ -327,33 +335,18 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 16, "metadata": {}, "outputs": [ { "data": { - "text/html": [ - "\n", - "
\n", - " \n", - " \n", - " Interrupted\n", - "
\n", - " " - ], + "application/vnd.jupyter.widget-view+json": { + "model_id": "2f87ba4562fd4d91b497f02086feeb8e", + "version_major": 2, + "version_minor": 0 + }, "text/plain": [ - "" + "Output()" ] }, "metadata": {}, @@ -370,7 +363,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 17, "metadata": {}, "outputs": [], "source": [ @@ -380,7 +373,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 18, "metadata": {}, "outputs": [], "source": [ @@ -397,7 +390,7 @@ " \n", " def on_iter_begin(self):\n", " self.html_code = '\\n'.join([html_progress_bar(0, self.main_bar.total, \"\"), \"\"])\n", - " self.out = display(HTML(self.html_code), display_id=True)\n", + " self.out = NBOutput(HTML(self.html_code))\n", "\n", " def on_interrupt(self):\n", " if self.clean_on_interrupt: self.out.update(HTML(''))\n", @@ -441,14 +434,14 @@ " if titles is None: titles = [None] * len(imgs)\n", " for img, ax, title in zip(imgs, imgs_axs.flatten(), titles): img.show(ax=ax, title=title)\n", " for ax in imgs_axs.flatten()[len(imgs):]: ax.axis('off')\n", - " if not hasattr(self, 'imgs_out'): self.imgs_out = display(self.imgs_fig, display_id=True)\n", + " if not hasattr(self, 'imgs_out'): self.imgs_out = NBOutput(self.imgs_fig)\n", " else: self.imgs_out.update(self.imgs_fig)\n", "\n", " def update_graph(self, graphs, x_bounds=None, y_bounds=None, figsize=(6,4)):\n", " if self.hide_graph: return\n", " if not hasattr(self, 'graph_fig'):\n", " self.graph_fig, self.graph_ax = plt.subplots(1, figsize=figsize)\n", - " self.graph_out = display(self.graph_ax.figure, display_id=True)\n", + " self.graph_out = NBOutput(self.graph_ax.figure)\n", " self.graph_ax.clear()\n", " if len(self.names) < len(graphs): self.names += [''] * (len(graphs) - len(self.names))\n", " for g,n in zip(graphs,self.names): self.graph_ax.plot(*g, label=n)\n", @@ -460,16 +453,18 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 19, "metadata": {}, "outputs": [ { "data": { - "text/html": [ - "Finished loop 0.

Finished loop 1.

Finished loop 2.

Finished loop 3.

Finished loop 4." - ], + "application/vnd.jupyter.widget-view+json": { + "model_id": "d02176e3a8eb4eb5b9222942b03c7ce7", + "version_major": 2, + "version_minor": 0 + }, "text/plain": [ - "" + "Output()" ] }, "metadata": {}, @@ -487,16 +482,18 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 20, "metadata": {}, "outputs": [ { "data": { - "text/html": [ - "Finished loop 0.

Finished loop 1.

Finished loop 2.

Finished loop 3.

Finished loop 4." - ], + "application/vnd.jupyter.widget-view+json": { + "model_id": "166b01f0d3ca40a89b6c8725f9a3e8e5", + "version_major": 2, + "version_minor": 0 + }, "text/plain": [ - "" + "Output()" ] }, "metadata": {}, @@ -524,7 +521,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 21, "metadata": {}, "outputs": [], "source": [ @@ -539,7 +536,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 22, "metadata": {}, "outputs": [], "source": [ @@ -550,7 +547,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 23, "metadata": {}, "outputs": [], "source": [ @@ -593,14 +590,16 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, + "execution_count": 24, + "metadata": { + "tags": [] + }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "█\r" + " |████████████████████████████████████████████████████████████████████████████████| 100.00% [100/100 00:05<00:00]\r" ] } ], @@ -611,14 +610,16 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, + "execution_count": 25, + "metadata": { + "tags": [] + }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "█\r" + " |█████████████████████████████████████-------------------------------------------| 47.00% [47/100 00:02<00:02]\r" ] } ], @@ -632,7 +633,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 26, "metadata": {}, "outputs": [], "source": [ @@ -646,7 +647,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 27, "metadata": {}, "outputs": [], "source": [ @@ -687,18 +688,20 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, + "execution_count": 28, + "metadata": { + "tags": [] + }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Finished loop 0.\n", - "Finished loop 1.\n", - "Finished loop 2.\n", - "Finished loop 3.\n", - "Finished loop 4.\n" + "Finished loop 0. \n", + "Finished loop 1. \n", + "Finished loop 2. \n", + "Finished loop 3. \n", + "Finished loop 4. \n" ] } ], @@ -714,18 +717,20 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, + "execution_count": 29, + "metadata": { + "tags": [] + }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Finished loop 0.\n", - "Finished loop 1.\n", - "Finished loop 2.\n", - "Finished loop 3.\n", - "Finished loop 4.\n" + "Finished loop 0. \n", + "Finished loop 1. \n", + "Finished loop 2. \n", + "Finished loop 3. \n", + "Finished loop 4. \n" ] } ], @@ -747,7 +752,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 30, "metadata": {}, "outputs": [], "source": [ @@ -758,7 +763,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 31, "metadata": {}, "outputs": [], "source": [ @@ -768,7 +773,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 32, "metadata": {}, "outputs": [], "source": [ @@ -780,7 +785,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 33, "metadata": {}, "outputs": [], "source": [ @@ -799,8 +804,10 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, + "execution_count": 34, + "metadata": { + "tags": [] + }, "outputs": [ { "name": "stdout", @@ -829,9 +836,21 @@ "split_at_heading": true }, "kernelspec": { - "display_name": "fastprogress", + "display_name": "Python 3", "language": "python", - "name": "fastprogress" + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.5" } }, "nbformat": 4,