enthought / enthought/chaco

monkey patch on event handler

Open
#562 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Python
Stars
305
Forks
97
PR merge metrics
No merged PRs in 30d

Description

Hello,

This is rather a Trait issue than a Chaco one, but as this is using Chaco I'm facing this issue, I post this here.

I use a function, monkey_patch, written by Guido himself, to overwrite function:
http://mail.python.org/pipermail/python-dev/2008-January/076194.html

If I apply this on a function, say img_plot(), it works.

If I apply this on an event handler, say _color_mapper_changed(), it does not work.

```"""
Draws a colormapped image plot
- 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".
"""

# Major library imports
from numpy import exp, linspace, meshgrid

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

# Chaco imports
from chaco.api import ArrayPlotData, viridis, Plot
from chaco.tools.api import PanTool, ZoomTool

from chaco.abstract_colormap import AbstractColormap
from chaco.data_range_1d import DataRange1D
# From http://mail.python.org/pipermail/python-dev/2008-January/076194.html
def monkeypatch_method(cls):

def decorator(func):
setattr(cls, func.__name__, func)
return func

return decorator

@monkeypatch_method(Plot)
def img_plot(self, data, name=None, colormap=None,
xbounds=None, ybounds=None, origin=None, hide_grids=True,
**styles):
print('img_plot() patched!')
if name is None:
name = self._make_new_plot_name()
if origin is None:
origin = self.default_origin

value = self._get_or_create_datasource(data)
array_data = value.get_data()
if len(array_data.shape) == 3:
if array_data.shape[2] not in (3,4):
raise ValueError("Image plots require color depth of 3 or 4.")
cls = self.renderer_map["img_plot"]
kwargs = dict(**styles)
else:
if colormap is None:
if self.color_mapper is None:
colormap = Spectral(DataRange1D(value))
else:
colormap = self.color_mapper
elif isinstance(colormap, AbstractColormap):
if colormap.range is None:
colormap.range = DataRange1D(value)
else:
colormap = colormap(DataRange1D(value))
self.color_mapper = colormap
cls = self.renderer_map["cmap_img_plot"]
kwargs = dict(value_mapper=colormap, **styles)
return self._create_2d_plot(cls, name, origin, xbounds, ybounds, value,
hide_grids, cell_plot=True, **kwargs)

@monkeypatch_method(Plot)
def _color_mapper_changed(self):
print('_color_mapper_changed() patched!')
for plist in self.plots.values():
for plot in plist:
plot.color_mapper = self.color_mapper
self.invalidate_draw()

#===============================================================================
# # Create the Chaco plot.
#===============================================================================
def _create_plot_component():
# Create a scalar field to colormap
xs = linspace(0, 10, 600)
ys = linspace(0, 5, 600)
x, y = meshgrid(xs,ys)
z = exp(-(x**2+y**2)/100)

# Create a plot data object 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=(0, 10),
ybounds=(0, 5),
colormap=viridis)[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=img_plot, tool_mode="box", always_on=False)
img_plot.overlays.append(zoom)
return plot

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

#===============================================================================
# # Demo class that is used by the demo.py application.
#===============================================================================
class Demo(HasTraits):
plot = Instance(Component)

traits_view = View(
Group(
Item('plot', editor=ComponentEditor(size=size),
show_label=False),
orientation = "vertical"),
resizable=True, title=title
)
def _plot_default(self):
return _create_plot_component()

demo = Demo()

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

Running this CME, one can see that the message "img_plot() patched!" is displayed
whereas "_color_mapper_changed()!" patched" is not.

Plot's img_plot() called is well the one in my CME, but it's the original code which is called for _color_mapper_changed(), not the one in my CME.

What am I doing wrong?

Any suggestion?

Thanks in advance.

Debian 10 x86_64, python 3.7.3
ETS source from github.

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.