如何在Bokeh(Python)中处理图像

20
例如,您可以使用以下代码在matplotlib中绘制图像:

例如,您可以使用以下代码在matplotlib中绘制图像:

%matplotlib inline
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
img=mpimg.imread('image.png')
plt.imshow(img)

Bokeh(0.10)可以做到类似这样的事情吗?


1
Bokeh有Image(标量数据,用于颜色映射),ImageRGBA(原始RGBA数据)和ImageURL(通过网络加载的图像)。这将是在GitHub问题跟踪器上提出的一个很好的功能请求。 - bigreddot
5个回答

27
您可以使用ImageURL图形(image_url绘图方法)从本地或网络加载图像。
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)

图片示例

注意 - 如果你只绘制一张图片(没有其他数据),你需要显式地设置绘图范围。

这里是文档:

http://docs.bokeh.org/en/latest/docs/reference/models/glyphs.html#bokeh.models.glyphs.ImageURL


5
这个示例代码在0.12.5上已经不再适用了,我试图编辑示例代码但被拒绝了两次,您需要使用以下调用来获取图片的URL: p.image_url(url=['tree.png'], x=0, y=0, w=1, h=1, anchor="bottom_left") - johnf
3
使用bokeh服务器时,该示例无法正常工作。它无法找到图像(404错误)。 - Cutú Chiqueño
有没有一种方法可以确保图像以1:1的比例呈现(实际大小,像素对像素等)? - Royi

10

之前的回答很有帮助。然而,我想要一个仅包含图像而没有其他附加对象的选项。因此,针对 Bokeh 版本 0.12.0 添加了答案,并删除了所有网格、轴和工具栏。

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)

2
figure 是一个方便的函数,它返回一个包含所有轴线/网格/工具设置的 bokeh.models.Plot 实例。或者,你可以实例化一个裸的 Plot 对象,并将图像添加到其中(避免了所有减法操作)。 - Luke Canavan
1
@Luke感谢您的评论,您是否可以分享一个可运行的代码。 - Jayant

6
另一种选择是在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)

Squirtle sprite

使用回调函数无法动态更新ImageURL。但是,通过将div视为普通的Python字符串,您可以这样做:div_image.text,例如:

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])

Pokemon selector

当然,图像源也可以指向本地文件。
(在Python 3.7.3和bokeh 1.2.0中进行了测试)

我正在尝试使用本地图像遵循此答案,但是Bokeh始终显示alt文本。我做错了什么?"""<img src="/Users/me/Documents/Projects/Another Project/ABCD/ImageViewer/date_time_images/20201102/024744.png" alt="i_broken">""" - Finncent Price

5

要使用bokeh serve运行此示例需要一些技巧。建议正确设置工作目录:

server_folder/
     +main.py
     +static/
         +logo.png

..并从server_folder目录上级目录运行bokeh serve命令

bokeh serve server_folder --show

那么这段代码对我有效。
#main.py file
from bokeh.plotting import figure, curdoc
x_range = (-20,-10) # could be anything - e.g.(0,1)
y_range = (20,30)
p = figure(x_range=x_range, y_range=y_range)
#img_path = 'https://docs.bokeh.org/en/latest/_static/images/logo.png'
img_path = 'server_folder/static/logo.png'
p.image_url(url=[img_path],x=x_range[0],y=y_range[1],w=x_range[1]-x_range[0],h=y_range[1]-y_range[0])
doc = curdoc()
doc.add_root(p)

enter image description here


0
这是一个简单的示例,它可以工作,几乎与您请求的简单格式相同:
from PIL import Image
import numpy as np 
from bokeh.plotting import figure, output_notebook, show
output_notebook()

#load image
im = Image.open('Segment_image.png') # just replace any image that you want here


p = figure()
imarray = np.array(im.convert("RGBA"))

plotted_image = p.image_rgba(image=[imarray.view("uint32").reshape(imarray.shape[:2])], x=0, y=0, dw=imarray.shape[0], dh=imarray.shape[1])
show(p)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接