注意:我将自己回答这个问题,以帮助将来遇到这个问题的其他人。如果您愿意,请随时提交您自己的答案,但要知道它已经回答了!
如何在 Chaco 中将具有一种颜色图的蒙版图像叠加到具有不同颜色图的另一张图像上?另外,如何为每个添加颜色条?
在 Chaco 中以这种方式覆盖图像没有很好的文档记录,但绝对是可能的。首先,如何用 chaco 绘制蒙版图像?使用 绘图时Plot().img_plot()
,Chaco 使用np.nan
值作为透明像素。例如,绘图:
img = np.eye(100)
img[img==0] = np.nan
将绘制具有透明背景的对角线。
但是,您实际上如何将这张图片叠加到另一张图片上呢?
有两种主要方法可以做到这一点。
OverlayPlotContainer
第二种方法的优点是两个图像将使用相同的轴。此外,如果您在与第一张相同的图中绘制第二张图像,它会保持相同的像素纵横比。这意味着,如果您绘制一个 100x100 的图像,然后在其上覆盖一个 50x50 的图像,则覆盖的图像将仅占从 (0,0) 开始的整个绘图的 25%。
第二种方法存在一些问题,所以我将解释如何纠正它们。
Plot
当您在同一个对象上绘制多个图像时(使用img_plot()
),默认情况下它们都将使用相同的 color_mapper。这意味着两者都将缩放到相同的范围。这可能不是所需的结果,因此您必须为两个图像创建新的 color_mappers。
这是一些带有 TraitsUI 的示例代码,它改编自 Qt 代码。
from traits.api import HasTraits, Instance
from traitsui.api import Item, View
from enable.api import ComponentEditor
from chaco.api import ArrayPlotData, Plot, ColorBar, LinearMapper, HPlotContainer, DataRange1D, ImageData
import chaco.default_colormaps
#
import numpy as np
class ImagePlot(HasTraits):
plot = Instance(HPlotContainer)
traits_view = View(
Item('plot', editor=ComponentEditor(), show_label=False), width=500, height=500, resizable=True, title="Chaco Plot")
def _plot_default(self):
bottomImage = np.reshape(np.repeat(np.linspace(0, 5, 100),100), (100,100))
topImage = np.eye(50)
topImage = topImage*np.reshape(np.repeat(np.linspace(-2, 2, 50),50), (50,50))
topImage[topImage==0] = np.nan
#
bottomImageData = ImageData()
bottomImageData.set_data(bottomImage)
#
topImageData = ImageData()
topImageData.set_data(topImage)
#
plotData = ArrayPlotData(imgData=bottomImageData, imgData2=topImageData)
plot = Plot(plotData, name='My Plot')
plot.img_plot("imgData")
plot.img_plot("imgData2")
# Note: DO NOT specify a colormap in the img_plot!
plot.aspect_ratio = 1.0
#
bottomRange = DataRange1D()
bottomRange.sources = [plotData.get_data("imgData")]
topRange = DataRange1D()
topRange.sources = [plotData.get_data("imgData2")]
plot.plots['plot0'][0].color_mapper = chaco.default_colormaps.gray(bottomRange)
plot.plots['plot1'][0].color_mapper = chaco.default_colormaps.jet(topRange)
#
colormapperBottom = plot.plots['plot0'][0].color_mapper
colormapperTop = plot.plots['plot1'][0].color_mapper
#
colorbarBottom = ColorBar(index_mapper=LinearMapper(range=colormapperBottom.range), color_mapper=colormapperBottom, orientation='v', resizable='v', width=30, padding=20)
colorbarBottom.padding_top = plot.padding_top
colorbarBottom.padding_bottom = plot.padding_bottom
#
colorbarTop = ColorBar(index_mapper=LinearMapper(range=colormapperTop.range), color_mapper=colormapperTop, orientation='v', resizable='v', width=30, padding=20)
colorbarTop.padding_top = plot.padding_top
colorbarTop.padding_bottom = plot.padding_bottom
#
container = HPlotContainer(resizable = "hv", bgcolor='transparent', fill_padding=True, padding=0)
container.spacing = 0
container.add(plot)
container.add(colorbarBottom)
container.add(colorbarTop)
#
return container
if __name__ == "__main__":
ImagePlot().configure_traits()
我并没有为此获得 100% 的信任,通过在线快速搜索,我发现您可以使用以下代码进行简单的叠加:
来源:
http://docs.enthought.com/chaco/user_manual/containers.html#overlayplotcontainer
参考代码:
class OverlayImageExample(HasTraits):
plot = Instance(OverlayImage)
traits_view = View(
Item('plot', editor=ComponentEditor(), show_label=False),
width=800, height=600, resizable=True
)
def _plot_default(self):
# Create data
x = linspace(-5, 15.0, 100)
y = jn(3, x)
pd = ArrayPlotData(index=x, value=y)
zoomable_plot = Plot(pd)
zoomable_plot.plot(('index', 'value'),
name='external', color='red', line_width=3)
# Attach tools to the plot
zoom = ZoomTool(component=zoomable_plot,
tool_mode="box", always_on=False)
zoomable_plot.overlays.append(zoom)
zoomable_plot.tools.append(PanTool(zoomable_plot))
# Create a second inset plot, not resizable, not zoom-able
inset_plot = Plot(pd)
inset_plot.plot(('index', 'value'), color='blue')
inset_plot.set(resizable = '',
bounds = [250, 150],
position = [450, 350],
border_visible = True
)
# Create a container and add our plots
container = OverlayPlotContainer()
container.add(zoomable_plot)
container.add(inset_plot)
return container