monkey patch on event handler
- 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.