Skip to content

AbstractPlotRenderers return different array shapes when passing a single point to map_screen #550

@mdsmarte

Description

@mdsmarte

Base2DPlot and BaseXYPlot both implement the AbstractPlotRenderer interface, in particular the map_screen method.

When a single (x, y) point is passed to Base2DPlot.map_screen, the returned array is of the form [[x, y]] (nested, shape = (1, 2)), as set by GridMapper.map_screen:

chaco/chaco/grid_mapper.py

Lines 114 to 123 in 4a66835

def map_screen(self, data_pts):
""" map_screen(data_pts) -> screen_array
Maps values from data space into screen space.
"""
xs, ys = transpose(data_pts)
screen_xs = self._xmapper.map_screen(xs)
screen_ys = self._ymapper.map_screen(ys)
screen_pts = column_stack([screen_xs, screen_ys])
return screen_pts

When a single (x, y) point is passed to BaseXYPlot.map_screen, the returned array is of the form [x, y] (flattened, shape = (2,)):

chaco/chaco/base_xy_plot.py

Lines 336 to 353 in 4a66835

def map_screen(self, data_array):
""" Maps an array of data points into screen space and returns it as
an array.
Implements the AbstractPlotRenderer interface.
"""
# data_array is Nx2 array
if len(data_array) == 0:
return []
x_ary, y_ary = transpose(data_array)
sx = self.index_mapper.map_screen(x_ary)
sy = self.value_mapper.map_screen(y_ary)
if self.orientation == "h":
return transpose(array((sx,sy)))
else:
return transpose(array((sy,sx)))

This difference forces objects that interact with AbstractPlotRenderers to make an assumption about the behavior of the map_screen method. For example, the DataLabelTool assumes the map_screen return shape matches that of BaseXYPlot for a single point ((2,)):

pointx, pointy = label.component.map_screen(label.data_point)
self._original_offset = (label.x - pointx, label.y - pointy)

And therefore this tool throws an exception when used with a Base2DPlot:

File "<REDACTED>/python3.6/site-packages/chaco/tools/data_label_tool.py", line 53, in drag_start
    pointx, pointy = label.component.map_screen(label.data_point)
ValueError: not enough values to unpack (expected 2, got 1)

even though it would otherwise be compatible.

This issue also looks like it applies to the map_data method although I have not tested it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions