From 966868cdd9a1d32df3c48858c24e01b9eb5fe7bd Mon Sep 17 00:00:00 2001 From: Zane Dufour Date: Fri, 12 May 2023 14:27:28 -0400 Subject: [PATCH 1/8] add ipython extension --- itermplot/ipython/__init__.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 itermplot/ipython/__init__.py diff --git a/itermplot/ipython/__init__.py b/itermplot/ipython/__init__.py new file mode 100644 index 0000000..55fe320 --- /dev/null +++ b/itermplot/ipython/__init__.py @@ -0,0 +1,23 @@ +""" +ipython extensions for image output handling. +e.g. + +```ipython +%load_ext itermplot.ipython +``` + +implemented based on https://ipython.readthedocs.io/en/stable/config/shell_mimerenderer.html +""" + +from . import imgcat + + +def register_mimerenderer(ipython, mime, handler): + ipython.display_formatter.active_types.append(mime) + ipython.display_formatter.formatters[mime].enabled = True + ipython.mime_renderers[mime] = handler + + +def load_ipython_extension(ipython): + register_mimerenderer(ipython, "image/png", imgcat) + register_mimerenderer(ipython, "image/jpeg", imgcat) From 2b727a925b13de61dfe054f1ecc45d1648bdb294 Mon Sep 17 00:00:00 2001 From: Zane Dufour Date: Fri, 12 May 2023 14:31:02 -0400 Subject: [PATCH 2/8] try to fix import --- itermplot/ipython/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/itermplot/ipython/__init__.py b/itermplot/ipython/__init__.py index 55fe320..e2b23f1 100644 --- a/itermplot/ipython/__init__.py +++ b/itermplot/ipython/__init__.py @@ -9,7 +9,7 @@ implemented based on https://ipython.readthedocs.io/en/stable/config/shell_mimerenderer.html """ -from . import imgcat +from .. import imgcat def register_mimerenderer(ipython, mime, handler): From 78d37ce760a0bddef3d20349960fc2d958a2f37d Mon Sep 17 00:00:00 2001 From: Zane Dufour Date: Fri, 12 May 2023 14:34:54 -0400 Subject: [PATCH 3/8] try adding filename descriptor --- itermplot/ipython/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/itermplot/ipython/__init__.py b/itermplot/ipython/__init__.py index e2b23f1..9597a0a 100644 --- a/itermplot/ipython/__init__.py +++ b/itermplot/ipython/__init__.py @@ -19,5 +19,5 @@ def register_mimerenderer(ipython, mime, handler): def load_ipython_extension(ipython): - register_mimerenderer(ipython, "image/png", imgcat) - register_mimerenderer(ipython, "image/jpeg", imgcat) + register_mimerenderer(ipython, "image/png", lambda img: imgcat(img, fn="img.png")) + register_mimerenderer(ipython, "image/jpeg", lambda img: imgcat(img, fn="img.jpg")) From 1f15109cceb35bee382266007fb3427228208ad4 Mon Sep 17 00:00:00 2001 From: Zane Dufour Date: Fri, 12 May 2023 14:38:50 -0400 Subject: [PATCH 4/8] add second argument to lambda fn --- itermplot/ipython/__init__.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/itermplot/ipython/__init__.py b/itermplot/ipython/__init__.py index 9597a0a..5881573 100644 --- a/itermplot/ipython/__init__.py +++ b/itermplot/ipython/__init__.py @@ -19,5 +19,9 @@ def register_mimerenderer(ipython, mime, handler): def load_ipython_extension(ipython): - register_mimerenderer(ipython, "image/png", lambda img: imgcat(img, fn="img.png")) - register_mimerenderer(ipython, "image/jpeg", lambda img: imgcat(img, fn="img.jpg")) + register_mimerenderer( + ipython, "image/png", lambda img, _: imgcat(img, fn="img.png") + ) + register_mimerenderer( + ipython, "image/jpeg", lambda img, _: imgcat(img, fn="img.jpg") + ) From 56a1ff910d7fc06b2aed01172b54416854f27a3c Mon Sep 17 00:00:00 2001 From: Zane Dufour Date: Fri, 12 May 2023 14:44:23 -0400 Subject: [PATCH 5/8] add debugging to imgcat process --- itermplot/ipython/__init__.py | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/itermplot/ipython/__init__.py b/itermplot/ipython/__init__.py index 5881573..593ddd7 100644 --- a/itermplot/ipython/__init__.py +++ b/itermplot/ipython/__init__.py @@ -18,10 +18,16 @@ def register_mimerenderer(ipython, mime, handler): ipython.mime_renderers[mime] = handler +def _imgcater(fn): + def _wrapper(img, _): + import pdb + + pdb.set_trace() + imgcat(img, fn=fn) + + return _wrapper + + def load_ipython_extension(ipython): - register_mimerenderer( - ipython, "image/png", lambda img, _: imgcat(img, fn="img.png") - ) - register_mimerenderer( - ipython, "image/jpeg", lambda img, _: imgcat(img, fn="img.jpg") - ) + register_mimerenderer(ipython, "image/png", _imgcater(fn="img.png")) + register_mimerenderer(ipython, "image/jpeg", _imgcater(fn="img.jpg")) From a7c73a54438442ad3891fb5486ccc9e36b24fe19 Mon Sep 17 00:00:00 2001 From: Zane Dufour Date: Fri, 12 May 2023 14:49:53 -0400 Subject: [PATCH 6/8] capture metadata for debugging --- itermplot/ipython/__init__.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/itermplot/ipython/__init__.py b/itermplot/ipython/__init__.py index 593ddd7..2c1b495 100644 --- a/itermplot/ipython/__init__.py +++ b/itermplot/ipython/__init__.py @@ -19,10 +19,8 @@ def register_mimerenderer(ipython, mime, handler): def _imgcater(fn): - def _wrapper(img, _): - import pdb - - pdb.set_trace() + def _wrapper(img, metadata): + breakpoint() imgcat(img, fn=fn) return _wrapper From 8f83f4823becb27eb1701e273ee95a0f033544c9 Mon Sep 17 00:00:00 2001 From: Zane Dufour Date: Fri, 12 May 2023 15:21:09 -0400 Subject: [PATCH 7/8] simplify implementation and document --- README.md | 11 +++++++++++ itermplot/ipython/__init__.py | 9 ++++----- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 758cdbe..7991ecf 100644 --- a/README.md +++ b/README.md @@ -121,6 +121,17 @@ Type "help", "copyright", "credits" or "license" for more information. You should see a plot! +### image mimetype support + +If you want to display a wider variety of objects using ipython's mimetype capturing, load our bundled ipython extension: + +```ipython +$ %load_ext itermplot.ipython +$ from PIL import Image +$ Image.open("my_cool_image.png") +# your image should be displayed +``` + ## Uninstall You can disable this backend by unsetting the `MPLBACKEND` environment variable. diff --git a/itermplot/ipython/__init__.py b/itermplot/ipython/__init__.py index 2c1b495..f6d06d7 100644 --- a/itermplot/ipython/__init__.py +++ b/itermplot/ipython/__init__.py @@ -18,14 +18,13 @@ def register_mimerenderer(ipython, mime, handler): ipython.mime_renderers[mime] = handler -def _imgcater(fn): - def _wrapper(img, metadata): - breakpoint() +def imgcat_factory(fn): + def _wrapper(img, _): imgcat(img, fn=fn) return _wrapper def load_ipython_extension(ipython): - register_mimerenderer(ipython, "image/png", _imgcater(fn="img.png")) - register_mimerenderer(ipython, "image/jpeg", _imgcater(fn="img.jpg")) + register_mimerenderer(ipython, "image/png", imgcat_factory(fn="img.png")) + register_mimerenderer(ipython, "image/jpeg", imgcat_factory(fn="img.jpg")) From 49507ba213d1c4c9b22ea1ac4cb25b4c2bb25ae6 Mon Sep 17 00:00:00 2001 From: Zane Dufour Date: Tue, 6 Jun 2023 09:08:59 -0400 Subject: [PATCH 8/8] try to handle displaying strings --- itermplot/__init__.py | 2 +- itermplot/ipython/__init__.py | 11 ++++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/itermplot/__init__.py b/itermplot/__init__.py index f95de5c..4703bfe 100644 --- a/itermplot/__init__.py +++ b/itermplot/__init__.py @@ -83,7 +83,7 @@ def rev(c): return x -def imgcat(data, fn="plot.pdf"): +def imgcat(data: bytes, fn="plot.pdf"): """Output the image data to the iTerm2 console. If `lines` is greater than zero then advance the console `lines` number of blank lines, move back, and then output the image. This is the default behaviour if TMUX diff --git a/itermplot/ipython/__init__.py b/itermplot/ipython/__init__.py index f6d06d7..1f08e05 100644 --- a/itermplot/ipython/__init__.py +++ b/itermplot/ipython/__init__.py @@ -20,7 +20,16 @@ def register_mimerenderer(ipython, mime, handler): def imgcat_factory(fn): def _wrapper(img, _): - imgcat(img, fn=fn) + if isinstance(img, bytes): + return imgcat(img, fn=fn) + elif hasattr(img, "read"): + return imgcat(img.read(), fn=fn) + elif isinstance(img, str): + return imgcat(img.encode(), fn=fn) + else: + raise ValueError( + "imgcat only accepts bytes, file-like objects, and strings" + ) return _wrapper