2016-11-19 2 views
1

Как пример, в chaco/examples/demo/basic/image_inspector.py, как установить коэффициент масштабирования таким образом, чтобы 1 точка массива соответствовала 1 пикселю экрана (100% масштабирование). Похоже, что методы ZoomTool (zoom_in, zoom_out, ...) касаются только изменений коэффициента масштабирования, а не настройки абсолютного коэффициента.Как получить коэффициент масштабирования 100% с помощью Chaco

ответ

0

Решение, к которому я пришел, начиная с оригинального примера image_inspector.py. Кнопка позволяет использовать коэффициент масштабирования 100% вокруг точки, выбранной в качестве центра масштабирования.

Все в _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() 
1

Я бы попробовал что-то с plot.range2d.low, plot.range2d.high и plot.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 заявления там, так что вы можете увидеть, что площадь участка отличается от площади окна, которое 800х600. Я также добавил PanTool и ZoomTool, так что вы можете перемещаться вокруг, когда вы увеличили масштаб. Вы можете вернуться к режиму масштабирования изображения с помощью клавиши Escape, пока ваш сюжет имеет ZoomTool.

Смежные вопросы