enthought / chaco

Chaco is a Python package for building interactive and custom 2-D plots.
http://docs.enthought.com/chaco/
Other
292 stars 99 forks source link

issue with LegendHighlighter tool #825

Closed fred4ets closed 1 year ago

fred4ets commented 2 years ago

Hello,

I have the following issue when I run the CME below:

if 'name' (line 52) is set to a string with only one character, LegendHighlighter does not work (does not highlight curve), whereas it runs without problem in any other case.

#!/usr/bin/env python
"""
Draws several overlapping line plots like simple_line.py, but uses a separate
Y range for j1 compared to the other 3 curves. Also has a second Y-axis on the
right hand side for j1. Demonstrates use of the BroadcasterTool.

Interactive behavior:
* Left-drag pans the plot.
* Right-click and dragging on the legend allows you to reposition the legend.
* Double-clicking on line or scatter plots brings up a traits editor for the
  plot.
"""

# Major library imports
from numpy import arange, cos

# Enthought library imports
from enable.api import Component, ComponentEditor
from traits.api import HasTraits, Instance
from traitsui.api import Item, VGroup, View

# Chaco imports
from chaco.api import (
    create_line_plot,
    add_default_axes,
    add_default_grids,
    OverlayPlotContainer,
    Legend,
)
from chaco.tools.api import (
    LegendHighlighter,
    TraitsTool,
)

# =============================================================================
# Create the Chaco plot.
# =============================================================================

def _create_plot_component():

    container = OverlayPlotContainer(
        padding=60, fill_padding=True, use_backbuffer=True, border_visible=True
    )

    # Create the initial X-series of data
    numpoints = 100
    low = -5
    high = 15.0
    x = arange(low, high + 0.001, (high - low) / numpoints)

    name = 'a'

    # Plot some bessel functions
    plots = {}
    y = cos(x)
    plot = create_line_plot((x, y))
    container.add(plot)
    plots[name] = plot
    add_default_grids(plot)
    add_default_axes(plot)
    # Create a legend, with tools to move it around and highlight renderers:
    legend = Legend(component=container, padding=10, align="ur")
    legend.tools.append(LegendHighlighter(legend))
    container.overlays.append(legend)
    # Set the list of plots on the legend
    legend.plots = plots

    # Add the traits inspector tool to the container
    container.tools.append(TraitsTool(container))

    return container

# =============================================================================
# Attributes to use for the plot view.
size = (800, 700)

# =============================================================================
# Demo class that is used by the demo.py application.
# =============================================================================

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

    traits_view = View(
        VGroup(
            Item("plot", editor=ComponentEditor(size=size), show_label=False)
        ),
        resizable=True,
        width=size[0],
        height=size[1],
    )

    def _plot_default(self):
        return _create_plot_component()

demo = Demo()

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

Any help would be appreciated.

Thanks in advance.

Regards

Python 3.9.2, Debian 11 x86_64, code source from github

corranwebster commented 1 year ago

Thanks for the report. I can replicate the issue.

fred4ets commented 1 year ago

Thanks a lot!

fred4ets commented 1 year ago

In fact, it still does not work :/

corranwebster commented 1 year ago

In fact, it still does not work :/

Hmmm... I had this working on my machine with your code snippet. You should have a larger target area now - clicking on the icon next to the label should work as well. But I will revisit in case something went wrong during the commit process - maybe even add a test.

FWIW, the issue was that there was an ad-hoc hack of taking the label coordinate and adding 20 pixels to get the position, but the actual width that was needed was closer to 30 pixels (but variable) which meant that when the length of the text was less than ~10 pixels there was no valid hitbox.

corranwebster commented 1 year ago

This is what I get when I try the PR branch on my machine:

https://github.com/enthought/chaco/assets/600761/42fe6f40-3074-4435-b48e-a114d7708682

fred4ets commented 1 year ago

This is good, now.

Thanks a lot again.