1

I am writing a small python package for interactive data visualisation. We would like to include gifs with the package so users can run an example and learn how to interact with the figure.

Here is an example structure:

<package>
    +-->some_module/
        +--> static/
            +--> foo.gif
        +--> spam.py
    +-->examples/
       +--> example.ipynb

We have several classes (e.g., spam.py may contain the class Spam), and these classes will have a method .show_gif() which will access the gif (foo.gif) within static and show it to the user.

The code is wrote to be used within a Jupyter notebook. In the package we include some examples (e.g., example.ipynb), these will import spam and then call the .show_gif() method on the relevant class.

Currently we display the gifs using:

from IPython.core.display import Image
Image(filename=path_to_gif)

which works fine when the gif is in a sub-directory of the folder the jupyter notebook is in, but not when the gif is within a sibling directory of the package (as in the above example).

EDIT:

I believe I can access the .gif but cannot display it in a jupyter notebook (see below)

There are similar stack overflow questions (This question) which suggest using importlib.resources module from the standard library. However, they return a BinaryIO instance I don't know how to deal with see:

import some_module.static as static

…

def show_gif(self):
    image = pkg_resources.open_binary(static, 'foo.gif')
    return Image(data=image)

this throws an error because I am giving Image a wrong type for data. How can I open this .gif and display it in a jupyter notebook?

FChm
  • 2,515
  • 1
  • 17
  • 37
  • 1
    Well, "I have tried this [importlib.resources] but receive an encoding error" is the problem you should be trying to solve. If you just copy-pasted `importlib.resources.open_text()` from the linked answer, change it to `importlib.resources.open_binary()`; GIFs are binary files. – alexis Jun 05 '19 at 11:16
  • I did try open_binary as well, but will have another go... – FChm Jun 05 '19 at 11:17
  • Thanks for your comment, I have updated the question (see EDIT). I am still looking at it but believe I need to convert the `image` returned by open_binary to an appropriate type for `Image` – FChm Jun 05 '19 at 11:35

1 Answers1

1

Use any method to find the path to your gif file and open it for reading; pkg_resources.open_binary() will do, though as this is an actual file on disk there are simpler methods. But now you have an open filehandle, not the content itself-- same as when you call open() on a file. To get the image data, you need to read() from the filehandle.

You then have a bytes object, not a text string. That's not a problem since Image() accepts bytes in the constructor:

with pkg_resources.open_binary(some_module, 'foo.gif') as src:
    imagedata = src.read()
image = Image(data=imagedata)
alexis
  • 48,685
  • 16
  • 101
  • 161