如何使用Chaco获得100%的缩放系数

时间:2016-11-19 18:32:48

标签: enthought chaco

例如,在chaco / examples / demo / basic / image_inspector.py中,如何设置缩放系数,使1个阵列点对应1个屏幕像素(100%缩放)。似乎ZoomTool方法(zoom_in,zoom_out,...)仅处理缩放系数变化,而不是绝对因子设置。

2 个答案:

答案 0 :(得分:1)

我会尝试使用plot.range2d.lowplot.range2d.highplot.outer_bounds。前两个涉及数据空间,而后者涉及图像区域的大小。通过使用图片区域设置数据空间的限制,您可以将1个像素映射到1个数据单元。这是一个例子,有趣的位在_zoom_100_percent方法中:

import numpy as np
from chaco.api import Plot, ArrayPlotData
from chaco.tools.api import PanTool, ZoomTool
from enable.api import ComponentEditor
from traits.api import Button, HasTraits, Instance, on_trait_change
from traitsui.api import Item, View

class HundredPercentZoom(HasTraits):
    plot = Instance(Plot)
    zoom_button = Button('100% Zoom')

    traits_view = View(
        Item('plot', editor=ComponentEditor(), show_label=False),
        'zoom_button',
        width=800,
        height=600,
    )

    def _plot_default(self):
        t = np.linspace(0, 1000, 200)
        y = 400 * (np.sin(t) + 0.1 * np.sin(t * 100))
        plot = Plot(ArrayPlotData(t=t, y=y))
        plot.plot(('t', 'y'))
        plot.tools.append(PanTool(plot))
        plot.tools.append(ZoomTool(plot))
        return plot

    @on_trait_change('zoom_button')
    def _zoom_100_percent(self):
        low = self.plot.range2d.low
        bounds = self.plot.outer_bounds
        print(bounds)
        self.plot.range2d.high = (low[0] + bounds[0], low[1] + bounds[1])

if __name__ == "__main__":
    hpz = HundredPercentZoom()
    hpz.configure_traits()

我在那里添加了print语句,因此您可以看到绘图区域与窗口区域不同,即800x600。我还添加了一个PanTool和ZoomTool,因此您可以在放大后进行平移。只要您的绘图具有ZoomTool,您就可以使用Escape键返回原始缩放状态。

答案 1 :(得分:0)

我已经到达的解决方案,从原始示例image_inspector.py开始。按钮允许在选择作为缩放中心的点周围具有100%缩放系数。

所有内容都在Demo课程中的 _btn_fired 方法中。

可能仍然存在1没有被减去或添加到某些界限或限制的问题,因为按钮操作不是严格意义上的(第二次按下不应该做任何事情)。

更简单吗?

#!/usr/bin/env python
"""
Demonstrates the ImageInspectorTool and overlay on a colormapped image
plot.  The underlying plot is similar to the one in cmap_image_plot.py.
 - Left-drag pans the plot.
 - Mousewheel up and down zooms the plot in and out.
 - Pressing "z" brings up the Zoom Box, and you can click-drag a rectangular
   region to zoom.  If you use a sequence of zoom boxes, pressing alt-left-arrow
   and alt-right-arrow moves you forwards and backwards through the "zoom
   history".
 - Pressing "p" will toggle the display of the image inspector overlay.
"""

# Major library imports
from numpy import linspace, meshgrid, pi, sin, divide, multiply

# Enthought library imports
from enable.api import Component, ComponentEditor
from traits.api import HasTraits, Instance, Button, Float
from traitsui.api import Item, Group, View, HGroup

# Chaco imports
from chaco.api import ArrayPlotData, jet, Plot
from chaco.tools.api import PanTool, ZoomTool
from chaco.tools.image_inspector_tool import ImageInspectorTool, \
     ImageInspectorOverlay

#===============================================================================
# # Create the Chaco plot.
#===============================================================================
def _create_plot_component():# Create a scalar field to colormap
    xbounds = (-2*pi, 2*pi, 600)
    ybounds = (-1.5*pi, 1.5*pi, 300)
    xs = linspace(*xbounds)
    ys = linspace(*ybounds)
    x, y = meshgrid(xs,ys)
    z = sin(x)*y

    # Create a plot data obect and give it this data
    pd = ArrayPlotData()
    pd.set_data("imagedata", z)

    # Create the plot
    plot = Plot(pd)
    img_plot = plot.img_plot("imagedata",
                             xbounds = xbounds[:2],
                             ybounds = ybounds[:2],
                             colormap=jet)[0]

    # Tweak some of the plot properties
    plot.title = "My First Image Plot"
    plot.padding = 50

    # Attach some tools to the plot
    plot.tools.append(PanTool(plot))
    zoom = ZoomTool(component=plot, tool_mode="box", always_on=False)
    plot.overlays.append(zoom)
    imgtool = ImageInspectorTool(img_plot)
    img_plot.tools.append(imgtool)
    overlay = ImageInspectorOverlay(component=img_plot, image_inspector=imgtool,
                                    bgcolor="white", border_visible=True)

    img_plot.overlays.append(overlay)
    return plot

#===============================================================================
# Attributes to use for the plot view.
size = (800, 600)
title="Inspecting a Colormapped Image Plot"

#===============================================================================
# # Demo class that is used by the demo.py application.
#===============================================================================
class Demo(HasTraits):
    plot = Instance(Component)
    center_x = Float
    center_y = Float
    btn = Button('100 %')

    def _btn_fired(self):
        img_plot, = self.plot.plots['plot0']
        zoom_center = (self.center_x, self.center_y)
        # Size of plot in screen pixels
        plot_size = img_plot.bounds
        # Zoom center in screen space
        zoom_center_screen, = img_plot.map_screen(zoom_center)
        # Get actual bounds in data space
        low, high = (img_plot.index_mapper.range.low, 
            img_plot.index_mapper.range.high)
        # Get data space x and y units in terms of x and y array indices
        sizes = [item.get_size() for item in img_plot.index.get_data()]
        (min_x, min_y), (max_x, max_y) = img_plot.index.get_bounds()
        unit = divide((max_x - min_x, max_y - min_y), sizes)
        # Calculate new bounds
        new_low = zoom_center - multiply(zoom_center_screen, unit)
        new_high = new_low + multiply(plot_size, unit)
        # Set new bounds
        img_plot.index_mapper.range.set_bounds(new_low,new_high)

    traits_view = View(
                    Group(
                        Item('plot', editor=ComponentEditor(size=size),
                             show_label=False),
                        HGroup('center_x', 'center_y', 'btn'),
                        orientation = "vertical"
                    ),
                    resizable=True, title=title
                    )

    def _plot_default(self):
         return _create_plot_component()

demo = Demo()

if __name__ == "__main__":
    demo.configure_traits()