Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8488229
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 10, 20262026-06-10T21:28:32+00:00 2026-06-10T21:28:32+00:00

I’m working on a program that has two plots next to each other. The

  • 0

I’m working on a program that has two plots next to each other. The first plot has a ZoomTool, a PanTool and a RangeSelection tool. The second plot should be modified according to the changes (zooming, etc.) made in the left plot.

Is there a possibility to get the new index and value after zooming? And how do I get the new index range after doing a rangeselection? This index schould also be the new index of the right plot until the selected part is no longer selected.

I will post my code below this text but you can also see it here

Here is my code:

#=================================================
# Code
#=================================================

# Enthought library imports
from traits.api import HasTraits, Int, Instance
from traits.api import *
from traitsui.api import Item, View, Group, HGroup, VGroup
from enable.api import Component
from enable.component_editor import ComponentEditor
from traitsui.menu import OKButton, CancelButton
# Chaco imports
from chaco.tools.api import RangeSelection, RangeSelectionOverlay
from chaco.chaco_plot_editor import ChacoPlotEditor, ChacoPlotItem
from chaco.api import Plot, ArrayPlotData, OverlayPlotContainer, create_line_plot, create_scatter_plot, add_default_axes, add_default_grids, PlotAxis, PlotLabel
from chaco.tools.api import PanTool, BroadcasterTool, ZoomTool
# Numpy imports
from numpy import linspace, pi, sin, tan

def main():
    # normally this function gets its values out of other files
    x1 = -2*pi
    x2 = pi
    y1 = 0
    y2 = 2
    uebergabe = {"xlim":[x1,x2], "ylim":[y1,y2], "ranges":[x1,x2]}
    return uebergabe


class Trait(HasTraits):
    plot = Instance(Component)    

    #creates the container
    container = OverlayPlotContainer(padding = 50, fill_padding = True,
                        bgcolor = "lightgray", use_backbuffer=True)
    container2 = OverlayPlotContainer(padding = 50, fill_padding = True,
                        bgcolor = "lightgray", use_backbuffer=True)

    # Traits
    xmin = Float
    xmax = Float
    ymin = Float
    ymax = Float
    rangeXMin = Float
    rangeXMax = Float

    # TraitsUI view
    traits_view = View(Group(
        HGroup(
            VGroup(Item("container", editor = ComponentEditor(), show_label = False)),
            VGroup(Item("container2", editor = ComponentEditor(), show_label = False))),        
        HGroup(Item("xmin"), Item("xmax"), Item("ymin"), Item("ymax"), show_border = True, label = "Plotborders"),
        HGroup(Item("rangeXMin", label="x_min"), Item("rangeXMax", label="x_max"), show_border = True, label="Range of right plot")), 
        buttons = [OKButton, CancelButton], resizable = True, width = 1000, height = 800)

    # Constructor
    def __init__(self):
        super(Trait, self).__init__()

        uebergabe = main()

        # initialize traits
        self.xmin = uebergabe["xlim"][0]
        self.xmax = uebergabe["xlim"][1]
        self.ymin = uebergabe["ylim"][0]
        self.ymax = uebergabe["ylim"][1]
        self.rangeXMin = uebergabe["ranges"][0]
        self.rangeXMin = uebergabe["ranges"][1]


        self._create_Container()


    def _create_Container(self):

        #creating dict of plots and the broadcaster
        plots = {}
        broadcaster = BroadcasterTool()

        #=====================first container===========================

        #first plot
        index = linspace(-2*pi,2*pi,1000)
        plot = create_line_plot((index, sin(index)+0.5), color = "blue", index_bounds=(self.xmin, self.xmax), value_bounds = (self.ymin, self.ymax))
        plot.bgcolor = "white"
        plot.border_visible = True
        value_mapper = plot.value_mapper
        index_mapper = plot.index_mapper
        add_default_grids(plot)
        add_default_axes(plot)

        # range selection
        self.rangeselect = RangeSelection(plot, left_button_selects = False, auto_handle_event = False)
        plot.active_tool = self.rangeselect
        plot.overlays.append(RangeSelectionOverlay(component=plot))

        #adds plot to the container
        self.container.add(plot)

        # second plot
        index2 = linspace(-5*pi,4*pi,1000)
        plot = create_line_plot((index2, tan(index2)), color = "black", index_bounds=(self.xmin, self.xmax), value_bounds = (self.ymin, self.ymax))
        plot.value_mapper = value_mapper
        value_mapper.range.add(plot.value)
        plot.index_mapper = index_mapper
        index_mapper.range.add(plot.index)

        # Create a pan tool and give it a reference to the plot
        pan = PanTool(plot, drag_button="left")
        broadcaster.tools.append(pan)

        # allows to zoom
        zoom = ZoomTool(plot, tool_mode="box", always_on = False, visible = True)
        plot.overlays.append(zoom)


        #adds plot to the container
        self.container.add(plot)

        # appends broadcaster to the container
        self.container.tools.append(broadcaster)

        # title of the container
        self.container.overlays.append(PlotLabel("left plot", component=self.container, overlay_position = "top"))

        #==============end of first container===========================

        #====================second container===========================

        #first plot2
        index3 = linspace(-10*pi,10*pi,500)
        plot2 = create_scatter_plot((index3, sin(index3)), color = "blue", index_bounds=(self.rangeXMin, self.rangeXMax), value_bounds = (self.ymin, self.ymax))
        plot2.bgcolor = "white"
        plot2.border_visible = True
        plot2.value_mapper = value_mapper # the plot uses the same index and
        plot2.index_mapper = index_mapper # value like the plots of container1
        #value_mapper.range.add(plot2.value)
        #index_mapper.range.add(plot2.index)
        add_default_grids(plot2)
        add_default_axes(plot2)

        #adds plot to the container
        self.container2.add(plot2)

        # title of the container
        self.container2.overlays.append(PlotLabel("right plot", component=self.container, overlay_position = "top"))

        #=============end of second container===========================
gui = Trait()
gui.configure_traits()
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-10T21:28:34+00:00Added an answer on June 10, 2026 at 9:28 pm

    You can use sync_trait() to Synchronizes value between two traits:

    self.sync_trait("xmin", index_mapper.range, "_low_value")
    self.sync_trait("xmax", index_mapper.range, "_high_value")
    self.sync_trait("ymin", value_mapper.range, "_low_value")
    self.sync_trait("ymax", value_mapper.range, "_high_value")
    
    self.sync_trait("rangeXMin", plot2.index_mapper.range, "low", False)
    self.sync_trait("rangeXMax", plot2.index_mapper.range, "high", False)
    

    To catch range selection changes:

    self.rangeselect.on_trait_change(self.on_selection_changed, "selection")
    
    def on_selection_changed(self, selection):
        if selection != None:
            self.rangeXMin, self.rangeXMax = selection
    

    To catch axis range changes:

    index_mapper.on_trait_change(self.on_mapper_updated, "updated")
    
    def on_mapper_updated(self, mapper, name, value):
        if not self.rangeselect.selection:
            self.rangeXMin = mapper.range.low
            self.rangeXMax = mapper.range.high
    

    Here is the full code:

    # -*- coding: utf-8 -*-
    #=================================================
    # Code
    #=================================================
    
    # Enthought library imports
    from traits.api import HasTraits, Int, Instance
    from traits.api import *
    from traitsui.api import Item, View, Group, HGroup, VGroup
    from enable.api import Component
    from enable.component_editor import ComponentEditor
    from traitsui.menu import OKButton, CancelButton
    # Chaco imports
    from chaco.tools.api import RangeSelection, RangeSelectionOverlay
    from chaco.chaco_plot_editor import ChacoPlotEditor, ChacoPlotItem
    from chaco.api import Plot, ArrayPlotData, OverlayPlotContainer, create_line_plot, create_scatter_plot, add_default_axes, add_default_grids, PlotAxis, PlotLabel
    from chaco.tools.api import PanTool, BroadcasterTool, ZoomTool
    # Numpy imports
    from numpy import linspace, pi, sin, tan
    
    def main():
        # normally this function gets its values out of other files
        x1 = -2*pi
        x2 = pi
        y1 = 0
        y2 = 2
        uebergabe = {"xlim":[x1,x2], "ylim":[y1,y2], "ranges":[x1,x2]}
        return uebergabe
    
    
    class Trait(HasTraits):
        plot = Instance(Component)    
    
        #creates the container
        container = OverlayPlotContainer(padding = 50, fill_padding = True,
                            bgcolor = "lightgray", use_backbuffer=True)
        container2 = OverlayPlotContainer(padding = 50, fill_padding = True,
                            bgcolor = "lightgray", use_backbuffer=True)
    
        # Traits
        xmin = Float
        xmax = Float
        ymin = Float
        ymax = Float
        rangeXMin = Float
        rangeXMax = Float
    
        # TraitsUI view
        traits_view = View(Group(
            HGroup(
                VGroup(Item("container", editor = ComponentEditor(), show_label = False)),
                VGroup(Item("container2", editor = ComponentEditor(), show_label = False))),        
            HGroup(Item("xmin"), Item("xmax"), Item("ymin"), Item("ymax"), show_border = True, label = "Plotborders"),
            HGroup(Item("rangeXMin", label="x_min"), Item("rangeXMax", label="x_max"), show_border = True, label="Range of right plot")), 
            buttons = [OKButton, CancelButton], resizable = True, width = 1000, height = 500)
    
        # Constructor
        def __init__(self):
            super(Trait, self).__init__()
    
            uebergabe = main()
    
            # initialize traits
            self.xmin = uebergabe["xlim"][0]
            self.xmax = uebergabe["xlim"][1]
            self.ymin = uebergabe["ylim"][0]
            self.ymax = uebergabe["ylim"][1]
            self.rangeXMin = uebergabe["ranges"][0]
            self.rangeXMin = uebergabe["ranges"][1]
    
    
            self._create_Container()
    
    
        def _create_Container(self):
    
            #creating dict of plots and the broadcaster
            plots = {}
            broadcaster = BroadcasterTool()
    
            #=====================first container===========================
    
            #first plot
            index = linspace(-2*pi,2*pi,1000)
            plot = create_line_plot((index, sin(index)+0.5), color = "blue", index_bounds=(self.xmin, self.xmax), value_bounds = (self.ymin, self.ymax))
            plot.bgcolor = "white"
            plot.border_visible = True
            value_mapper = plot.value_mapper
            index_mapper = plot.index_mapper
            add_default_grids(plot)
            add_default_axes(plot)
    
            self.sync_trait("xmin", index_mapper.range, "_low_value")
            self.sync_trait("xmax", index_mapper.range, "_high_value")
            self.sync_trait("ymin", value_mapper.range, "_low_value")
            self.sync_trait("ymax", value_mapper.range, "_high_value")
    
            # range selection
            self.rangeselect = RangeSelection(plot, left_button_selects = False, auto_handle_event = False)
            plot.active_tool = self.rangeselect
            plot.overlays.append(RangeSelectionOverlay(component=plot))
            self.rangeselect.on_trait_change(self.on_selection_changed, "selection")
    
            #adds plot to the container
            self.container.add(plot)
    
            # second plot
            index2 = linspace(-5*pi,4*pi,1000)
            plot = create_line_plot((index2, tan(index2)), color = "black", index_bounds=(self.xmin, self.xmax), value_bounds = (self.ymin, self.ymax))
            plot.value_mapper = value_mapper
            value_mapper.range.add(plot.value)
            plot.index_mapper = index_mapper
            index_mapper.range.add(plot.index)
    
            # Create a pan tool and give it a reference to the plot
            pan = PanTool(plot, drag_button="left")
            broadcaster.tools.append(pan)
    
            # allows to zoom
            zoom = ZoomTool(plot, tool_mode="box", always_on = False, visible = True)
            plot.overlays.append(zoom)
    
    
            #adds plot to the container
            self.container.add(plot)
    
            # appends broadcaster to the container
            self.container.tools.append(broadcaster)
    
            # title of the container
            self.container.overlays.append(PlotLabel("left plot", component=self.container, overlay_position = "top"))
    
            #==============end of first container===========================
    
            #====================second container===========================
    
            #first plot2
            index3 = linspace(-10*pi,10*pi,500)
            plot2 = create_scatter_plot((index3, sin(index3)), color = "blue", index_bounds=(self.rangeXMin, self.rangeXMax), value_bounds = (self.ymin, self.ymax))
            plot2.bgcolor = "white"
            plot2.border_visible = True
            plot2.value_mapper = value_mapper # the plot uses the same index and
            #plot2.index_mapper = index_mapper # value like the plots of container1
            self.sync_trait("rangeXMin", plot2.index_mapper.range, "low", False)
            self.sync_trait("rangeXMax", plot2.index_mapper.range, "high", False)
    
    
            plot2.index_mapper.range.low = 0
            plot2.index_mapper.range.high = 2        
            #value_mapper.range.add(plot2.value)
            #index_mapper.range.add(plot2.index)
            add_default_grids(plot2)
            add_default_axes(plot2)
    
            #adds plot to the container
            self.container2.add(plot2)
    
            # title of the container
            self.container2.overlays.append(PlotLabel("right plot", component=self.container, overlay_position = "top"))
    
            index_mapper.on_trait_change(self.on_mapper_updated, "updated")
    
            #=============end of second container===========================
    
        def on_mapper_updated(self, mapper, name, value):
            if not self.rangeselect.selection:
                self.rangeXMin = mapper.range.low
                self.rangeXMax = mapper.range.high
    
        def on_selection_changed(self, selection):
            if selection != None:
                self.rangeXMin, self.rangeXMax = selection
    
    gui = Trait()
    gui.configure_traits()
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I'm parsing an RSS feed that has an ’ in it. SimpleXML turns this
That's pretty much it. I'm using Nokogiri to scrape a web page what has
Basically, what I'm trying to create is a page of div tags, each has
I've got a string that has curly quotes in it. I'd like to replace
I know there's a lot of other questions out there that deal with this
I'm working with an upstream system that sometimes sends me text destined for HTML/XML
link Im having trouble converting the html entites into html characters, (&# 8217;) i
I want to count how many characters a certain string has in PHP, but
I have a string like this: La Torre Eiffel paragonata all’Everest What PHP function
I have a French site that I want to parse, but am running into

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.