I want to create a circle plot with Bokeh, with an image in background, see the code bellow. I can't figure out why the image is not displayed. Is there something wrong in my code, or the method I use is not the proper one?
import pandas as pd
import cv2
from bokeh.models import ImageURL, ColumnDataSource
from bokeh.plotting import figure
from bokeh.models.ranges import DataRange1d
from bokeh.io import show
df = pd.DataFrame({'Time': [2586, 2836, 2986, 3269, 3702],
'X': [120, 210, 80, 98, 40],
'Y': [230, 40, 33, 122, 10],
'User': ['u1', 'u1', 'u2', 'u2', 'u2']})
source = ColumnDataSource(data=dict(time=df['Time'], x=df['X'], y=df['Y'], user=df['User']))
#read image
img_url = 'tree.jpg'
image=cv2.imread(img_url)
sx = image.shape[1]
sy = image.shape[0]
x_range = DataRange1d(start = 0, end = sx, bounds = (0, sx), range_padding = 5, range_padding_units = 'percent')
y_range = DataRange1d(start = sy, end = 0, bounds = (0, sy), range_padding = 5, range_padding_units = 'percent')
pw = 600
ph = int(pw * sy / sx)
# Create the figure: p
p = figure(x_axis_label='X', y_axis_label='Y', plot_width = pw, plot_height = ph,
x_range=x_range, y_range=y_range, match_aspect=True)
p.image_url(url=[img_url], x = 0, y = 0, w = sx, h = sy, anchor="top_right")
p.circle(x='x', y='y', source=source, size=10, color='blue', fill_color='white', alpha=0.8)
show(p)
img_url
needs to be a proper URL that the resulting page is able to access. A local file system path to a file is not a URL. Unfortunately, you cannot use image_url
with a local file without using some sort of a web server because web pages cannot access local files for security reasons. Two feasible options that I can think of:
bokeh serve
with a directory-based app. It will allow you to serve arbitrary files via the static
directoryimage_url
, use image_rgba
. You already read the whole image, so you can just serve it as data instead of serving it as a URLIf you can't make image_url
work, try playing with its anchor and make sure that the url
parameter starts with the name of the directory. I could display the image by creating a directory named test_app
:
test_app
├── main.py
└── static
└── tree.png
where main.py
has only
from bokeh.io import curdoc
from bokeh.plotting import figure
p = figure()
p.image_url(url=['/test_app/static/tree.png'],
x=[0], y=[0], w=[1], h=[1], anchor="bottom_left")
curdoc().add_root(p)
It should be run as bokeh serve test_app
.