4
votes

I'm emulating the Hovertool example here, where the hovertool displays images of snakes. My own data consists of names of people, and their profile pictures. I have a local directory of all profile pics, so whenever I get a list of names, names_ls, I have a method get_profile_pics which will search that directory* for the profile picture associated with the names on that list.

Note how, in the snakes example (code from the example reproduced below for convenience) the images imgs are stored in the ColumnDataSource data dictionary as html urls. I want to try to display images that are stored on my local drive instead, how could I go about doing that?

Some pointers:

  1. Assume that I will always have a profile pic of whatever names I'm given. Many people can have the same name, but get_profile_pics takes care of that.
  2. I'd like to run all this in a jupyter notebook.
  3. The pics are .pngs, and I've also saved those profile pics as .npy files, if that helps.
  4. Because of privacy issues, I don't want to host the images on the net to retrieve using a html tag.

Snakes Hovertool example code

source = ColumnDataSource(
        data=dict(
            x=[1, 2, 3, 4, 5],
            y=[2, 5, 8, 2, 7],
            desc=['A', 'b', 'C', 'd', 'E'],
            imgs = [
                'http://docs.bokeh.org/static/snake.jpg',
                'http://docs.bokeh.org/static/snake2.png',
                'http://docs.bokeh.org/static/snake3D.png',
                'http://docs.bokeh.org/static/snake4_TheRevenge.png',
                'http://docs.bokeh.org/static/snakebite.jpg'
            ]
        )
    )

hover = HoverTool(
        tooltips="""
        <div>
            <div>
                <img
                    src="@imgs" height="42" alt="@imgs" width="42"
                    style="float: left; margin: 0px 15px 15px 0px;"
                    border="2"
                ></img>
            </div>
        <...other div tags for text>
        """
    )

I've tried various formats: as PIL.Image images, as np.arrays, and as bytes. tldr: none of these work. My code, for completeness:

list_of_pics_PIL = [...]
list_of_pics_np = [...]
list_of_pics_png = [...]
type(list_of_pics_PIL[0]) #PIL.Image.Image
type(list_of_pics_np[0]) #numpy.ndarray
type(list_of_pics_png[0]) #bytes

selected_pics_PIL = get_profile_pics(names_ls, list_of_pics_PIL)
selected_pics_np = get_profile_pics(names_ls, list_of_pics_np)
selected_pics_png = get_profile_pics(names_ls, list_of_pics_png)

source = ColumnDataSource(
        data=dict(
            names = list_of_names,
            height = person_height,
            pics = selected_pics_<format>
            )
       )

hover = HoverTool(
        tooltips="""
        <div>
            <div>
                <img
                    src="@pics" height="42" alt="@imgs" width="42"
                    style="float: left; margin: 0px 15px 15px 0px;"
                    border="2"
                ></img>
            </div>
        <...other div tags for text>
        """
    )
2

2 Answers

0
votes

replace @pics with file://@pics and enjoy.

0
votes

To insert an image in a custom hovertool template, the image needs to be available at some public URL so that you can put in a standard HTML <img> tag in the template. It might if the images were base64-encoded data-urls in the CDS.