Error rendering splitview images
psychemedia opened this issue · 11 comments
Thanks for the report!
What operating system are you on?
I've done the development on MAC OS, but I think this package should be platform independent.
Here is my suggestion:
- Run once
pip install jupyter-splitview --upgrade
I've updated to version 0.0.4 just now, maybe the error will disappear there.
-
Can you check your internet connection?
When executing the widget, third party JavaScript is loaded from https://github.com/NUKnightLab/juxtapose, so maybe there was an error there. -
Can you try this widget once in firefox or any other browser than chrome?
I've just tested this widget in Chrome and Firefox and Safari, and all works well.
And can you run these two cells ones? They are the minimal implementation of the widget core.
The output should look like this:
from IPython.core.display import HTML
from IPython.display import display
html_code = f"""
<div class="outer_layer" style="position: relative; padding-top: 300px;">
<div class="juxtapose" data-startingposition="35%" style="height: 400px; width: 400px; top: 1%; left: 1%; position: absolute;">
<img src="https://raw.githubusercontent.com/scikit-image/scikit-image/main/skimage/data/chelsea.png" />' <img src="https://raw.githubusercontent.com/scikit-image/scikit-image/main/skimage/data/coins.png" />'
</div>
</div>
"""
display(HTML(html_code))
from IPython.core.display import HTML
from IPython.display import display
html_code = f"""
<div class="outer_layer" style="position: relative; padding-top: 300px;">
<div class="juxtapose" data-startingposition="35%" style="height: 400px; width: 400px; top: 1%; left: 1%; position: absolute;">
<img src="https://raw.githubusercontent.com/scikit-image/scikit-image/main/skimage/data/chelsea.png" />' <img src="https://raw.githubusercontent.com/scikit-image/scikit-image/main/skimage/data/coins.png" />'
</div>
</div>
<script src="https://cdn.knightlab.com/libs/juxtapose/latest/js/juxtapose.min.js"></script>
<link rel="stylesheet" href="https://cdn.knightlab.com/libs/juxtapose/latest/css/juxtapose.css" />
"""
display(HTML(html_code))
Those both render okay.
And now when I run the split view code, I actually get an error?
UnidentifiedImageError: cannot identify image file <_io.BytesIO object at 0x7fe528331720>
---------------------------------------------------------------------------
UnidentifiedImageError Traceback (most recent call last)
/tmp/ipykernel_801/2472879159.py in <module>
----> 1 get_ipython().run_cell_magic('splity', '--position 73% --height auto', 'import matplotlib.pyplot as plt\nimport numpy as np\n\narray1 = np.full((15, 30), 10)\narray2 = np.random.randint(0, 10, size=(15, 30))\nfig, ax1 = plt.subplots(figsize=(5, 10))\nax1.imshow(array1)\nfig, ax2 = plt.subplots(figsize=(5, 10))\nax2.imshow(array2)\n')
/usr/local/lib/python3.8/dist-packages/IPython/core/interactiveshell.py in run_cell_magic(self, magic_name, line, cell)
2401 with self.builtin_trap:
2402 args = (magic_arg_s, cell)
-> 2403 result = fn(*args, **kwargs)
2404 return result
2405
/usr/local/lib/python3.8/dist-packages/decorator.py in fun(*args, **kw)
230 if not kwsyntax:
231 args, kw = fix(args, kw, sig)
--> 232 return caller(func, *(extras + args), **kw)
233 fun.__name__ = func.__name__
234 fun.__doc__ = func.__doc__
/usr/local/lib/python3.8/dist-packages/IPython/core/magic.py in <lambda>(f, *a, **k)
185 # but it's overkill for just that one bit of state.
186 def magic_deco(arg):
--> 187 call = lambda f, *a, **k: f(*a, **k)
188
189 if callable(arg):
~/.local/lib/python3.8/site-packages/jupyter_splitview/sw_cellmagic.py in splity(self, line, cell)
53 imgdata = b64decode(out_images_base64[0])
54 # maybe possible without the PIL dependency?
---> 55 im = Image.open(io.BytesIO(imgdata))
56 width, height = im.size
57 widget_height = height
~/.local/lib/python3.8/site-packages/PIL/Image.py in open(fp, mode, formats)
3121 for message in accept_warnings:
3122 warnings.warn(message)
-> 3123 raise UnidentifiedImageError(
3124 "cannot identify image file %r" % (filename if filename else fp)
3125 )
UnidentifiedImageError: cannot identify image file <_io.BytesIO object at 0x7fe528331720>
Seems like the images are not captured the right way.
Can you once run this in the first cell:
import io
from base64 import b64decode
from IPython.core import magic_arguments
from IPython.core.display import HTML
from IPython.core.magic import Magics, cell_magic, magics_class
from IPython.display import display
from IPython.utils.capture import capture_output
from PIL import Image
@magics_class
class SplitViewMagic(Magics):
@magic_arguments.magic_arguments()
@magic_arguments.argument(
"--position",
"-p",
default="50%",
help=("The position where the slider starts"),
)
@magic_arguments.argument(
"--height",
"-h",
default="300",
help=(
"The height that the widget has. The width will be adjusted automatically. \
If height is choosen 'auto', the height will be defined by the resolution \
in vertical direction of the first image."
),
)
@cell_magic
def splity(self, line, cell):
"""Saves the png image and calls the splitview canvas"""
with capture_output(stdout=False, stderr=False, display=True) as result:
self.shell.run_cell(cell)
# saves all jupyter output images into the out_images_base64 list
out_images_base64 = []
print(f"{out_images_base64 = }")
for output in result.outputs:
data = output.data
print(f"{type(data) = }")
print(f"{type(list(data.values())[0]) = }")
if "image/png" in data:
png_bytes_data = data["image/png"]
out_images_base64.append(png_bytes_data)
print(f"{len(out_images_base64) = }")
# get the parameters the configure the widget
args = magic_arguments.parse_argstring(SplitViewMagic.splity, line)
slider_position = args.position
widget_height = args.height
if widget_height == "auto":
imgdata = b64decode(out_images_base64[0])
# maybe possible without the PIL dependency?
im = Image.open(io.BytesIO(imgdata))
width, height = im.size
widget_height = height
html_code = f"""
<div class="outer_layer" style="position: relative; padding-top: {int(widget_height)+3}px;">
<div class="juxtapose" data-startingposition="{slider_position}" style="height: {int(widget_height)}px;; width: auto; top: 1%; left: 1%; position: absolute;">
<img src="data:image/jpeg;base64,{out_images_base64[0]}" />' <img src="data:image/jpeg;base64,{out_images_base64[1]}" />'
</div>
</div>
<script src="https://cdn.knightlab.com/libs/juxtapose/latest/js/juxtapose.min.js"></script>
<link rel="stylesheet" href="https://cdn.knightlab.com/libs/juxtapose/latest/css/juxtapose.css" />
"""
display(HTML(html_code))
from IPython import get_ipython # register cell magic
ipy = get_ipython()
ipy.register_magics(SplitViewMagic)
and this in the second cell?
%%splity --position 73%
import matplotlib.pyplot as plt
import numpy as np
array1 = np.full((15, 30), 10)
array2 = np.random.randint(0, 10, size=(15, 30))
fig, ax1 = plt.subplots(figsize=(5, 10))
ax1.imshow(array1)
fig, ax2 = plt.subplots(figsize=(5, 10))
ax2.imshow(array2)
Output should be:
out_images_base64 = []
type(data) = <class 'dict'>
type(list(data.values())[0]) = <class 'str'>
type(data) = <class 'dict'>
type(list(data.values())[0]) = <class 'str'>
type(data) = <class 'dict'>
type(list(data.values())[0]) = <class 'str'>
len(out_images_base64) = 2
Yep - matches on those.
As the rendered HTML cell output I get:
<div class="lm-Widget p-Widget jp-RenderedHTMLCommon jp-RenderedHTML jp-mod-trusted jp-OutputArea-output" data-mime-type="text/html">
<div class="outer_layer" style="position: relative; padding-top: 303px;">
<div class="juxtapose juxtapose-2" data-startingposition="73%" style="height: 300px;; width: auto; top: 1%; left: 1%; position: absolute;"></div>
</div>
<script src="https://cdn.knightlab.com/libs/juxtapose/latest/js/juxtapose.min.js"></script>
<link rel="stylesheet" href="https://cdn.knightlab.com/libs/juxtapose/latest/css/juxtapose.css">
</div>
(Apols for not helping debug this more; I'm rushing about all w/e... Will try to get a look at it next week. It seems the image tag appears briefly as a broken image then disappears, so I guess the encoding/data URI bit is mangled somehow?!)
Does it work in MyBinder?
Does it work in MyBinder?
I have not tried it there, but feel free to give it a shot!
If it works, a pull request with a binder badge in the README is very welcome.
I've run the widget on multiple machines, and I've not run into an error, so it's not possible for me to reproduce your problem.
I think with the combination of the above scripts + some Stack Overflow research, you have good potential to solve this issue and in case that it can be solved, feel very welcome to make a pull request with the fix as well.
Any updates on this?
@psychemedia : As you can see here https://github.com/kolibril13/jupyter-splitview#005 there was a lot of activity recently on this repo, the whole project infrastructure got refactored, so I think it's worth once testing the newest version of this package by pip install jupyter-splitview --upgrade
and see if your error still occurs.
Okay- thanks.
[UPDATE: works fine now; thanks...]
I am glad to hear that!
In case that you have some time and motivation, would you like to contribute a binder example? :)