How do I work with images in Bokeh (Python)
For example you can plot an image in matplotlib using this code:
%matplotlib inline
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
img=mpimg.imread('image.png')
plt.imshow(img)
Is something like this possible with Bokeh(0.10)?
Solution 1:
You can use the ImageURL
glyph (image_url
plot method)to load images locally or from the web.
from bokeh.plotting import figure, show, output_file
output_file('image.html')
p = figure(x_range=(0,1), y_range=(0,1))
p.image_url(url=['tree.png'], x=0, y=1, w=0.8, h=0.6)
## could also leave out keywords
# p.image_url(['tree.png'], 0, 1, 0.8, h=0.6)
show(p)
One gotcha - if you graph only an image (and no other data), you'll have to explicitly set the plot ranges.
Here's the docs:
http://docs.bokeh.org/en/latest/docs/reference/models/glyphs.html#bokeh.models.glyphs.ImageURL
Solution 2:
The earlier answer was helpful. However, I wanted an image only option without any additional object. So, adding the answer for Bokeh version 0.12.0 and removed all the grids, axes and toolbar.
from bokeh.plotting import figure, curdoc
from bokeh.models import ColumnDataSource, Range1d
bosch_logo = "static/tree.jpg"
logo_src = ColumnDataSource(dict(url = [bosch_logo]))
page_logo = figure(plot_width = 500, plot_height = 500, title="")
page_logo.toolbar.logo = None
page_logo.toolbar_location = None
page_logo.x_range=Range1d(start=0, end=1)
page_logo.y_range=Range1d(start=0, end=1)
page_logo.xaxis.visible = None
page_logo.yaxis.visible = None
page_logo.xgrid.grid_line_color = None
page_logo.ygrid.grid_line_color = None
page_logo.image_url(url='url', x=0.05, y = 0.85, h=0.7, w=0.9, source=logo_src)
page_logo.outline_line_alpha = 0
curdoc().add_root(page_logo)
Solution 3:
Another option is to display the image in a div.:
from bokeh.io import output_notebook, show
from bokeh.models.widgets import Div
output_notebook()
div_image = Div(text="""<img src="https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/7.png" alt="div_image">""", width=150, height=150)
show(div_image)
ImageURL can't get updated dynamically with a callback. However, using a div
, you can do so by treating the div_image.text
as a regular Python string, for example:
from ipywidgets import interact
from bokeh.io import output_notebook, show, push_notebook
from bokeh.models.widgets import Div
output_notebook()
div_image = Div(text="""<img src="https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/1.png" alt="div_image">""", width=100, height=100)
def update(pokemon_number=1):
div_image.text = """<img src="https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/{}.png" alt="div_image">""".format(pokemon_number)
push_notebook()
show(div_image, notebook_handle=True)
interact(update, pokemon_number=[1, 4, 7])
Of course, the image source can also point to a local file.
(Tested in Python 3.7.3 and bokeh 1.2.0)