Repository: enthought/chaco

Issue:
[Examples] Scalar image function inspector is broken on Py3
Running the example raises a `ValueError`. Py3.6.0 and OSX.
See http://docs.enthought.com/chaco/user_manual/annotated_examples.html#scalar-image-function-inspector-py

```
(empty_py3_env)examples (master)$ python demo/advanced/scalar_image_function_inspector.py 
/Users/rahulporuri/.edm/envs/empty_py3_env/lib/python3.6/site-packages/chaco/array_data_source.py:123: FutureWarning: comparison to `None` will result in an elementwise object comparison in the future.
  self._data = newdata
/Users/rahulporuri/.edm/envs/empty_py3_env/lib/python3.6/site-packages/traits/trait_handlers.py:1603: FutureWarning: comparison to `None` will result in an elementwise object comparison in the future.
  if value in self.values:
/Users/rahulporuri/.edm/envs/empty_py3_env/lib/python3.6/site-packages/chaco/image_data.py:194: FutureWarning: comparison to `None` will result in an elementwise object comparison in the future.
  self._data = newdata
/Users/rahulporuri/.edm/envs/empty_py3_env/lib/python3.6/site-packages/chaco/axis.py:498: FutureWarning: comparison to `None` will result in an elementwise object comparison in the future.
  for tickpos in mapped_tick_positions]))
/Users/rahulporuri/.edm/envs/empty_py3_env/lib/python3.6/site-packages/chaco/axis.py:499: FutureWarning: comparison to `None` will result in an elementwise object comparison in the future.
  self._tick_label_list = tick_list
/Users/rahulporuri/.edm/envs/empty_py3_env/lib/python3.6/site-packages/chaco/axis.py:500: FutureWarning: comparison to `None` will result in an elementwise object comparison in the future.
  self._tick_label_positions = self._tick_positions
/Users/rahulporuri/.edm/envs/empty_py3_env/lib/python3.6/site-packages/kiva/fonttools/font_manager.py:1308: UserWarning: findfont: Font family ['sans-serif'] not found. Falling back to Bitstream Vera Sans
  (prop.get_family(), self.defaultFamily[fontext]))
/Users/rahulporuri/.edm/envs/empty_py3_env/lib/python3.6/site-packages/kiva/fonttools/font_manager.py:1318: UserWarning: findfont: Could not match (['Bitstream Vera Sans'], 'normal', None, 'normal', 500, 10.0). Returning /Library/Fonts/Andale Mono.ttf
  UserWarning)
Traceback (most recent call last):
  File "/Users/rahulporuri/.edm/envs/empty_py3_env/lib/python3.6/site-packages/enable/qt4/base_window.py", line 198, in paintEvent
    self.handler.paintEvent(event)
  File "/Users/rahulporuri/.edm/envs/empty_py3_env/lib/python3.6/site-packages/enable/qt4/base_window.py", line 50, in paintEvent
    self._enable_window._paint(event)
  File "/Users/rahulporuri/.edm/envs/empty_py3_env/lib/python3.6/site-packages/enable/abstract_window.py", line 468, in _paint
    self.component.draw(gc, view_bounds=(0, 0, size[0], size[1]))
  File "/Users/rahulporuri/.edm/envs/empty_py3_env/lib/python3.6/site-packages/enable/component.py", line 424, in draw
    self._draw(gc, view_bounds, mode)
  File "/Users/rahulporuri/.edm/envs/empty_py3_env/lib/python3.6/site-packages/enable/component.py", line 776, in _draw
    self._dispatch_draw(layer, gc, view_bounds, mode)
  File "/Users/rahulporuri/.edm/envs/empty_py3_env/lib/python3.6/site-packages/enable/container.py", line 272, in _dispatch_draw
    component._dispatch_draw(layer, gc, new_bounds, mode)
  File "/Users/rahulporuri/.edm/envs/empty_py3_env/lib/python3.6/site-packages/enable/container.py", line 270, in _dispatch_draw
    component._draw(gc, new_bounds, mode)
  File "/Users/rahulporuri/.edm/envs/empty_py3_env/lib/python3.6/site-packages/enable/component.py", line 766, in _draw
    self._dispatch_draw(layer, bb, view_bounds, mode)
  File "/Users/rahulporuri/.edm/envs/empty_py3_env/lib/python3.6/site-packages/enable/container.py", line 272, in _dispatch_draw
    component._dispatch_draw(layer, gc, new_bounds, mode)
  File "/Users/rahulporuri/.edm/envs/empty_py3_env/lib/python3.6/site-packages/enable/component.py", line 796, in _dispatch_draw
    handler(gc, view_bounds, mode)
  File "/Users/rahulporuri/.edm/envs/empty_py3_env/lib/python3.6/site-packages/chaco/base_2d_plot.py", line 204, in _draw_image
    self._render(gc)
  File "/Users/rahulporuri/.edm/envs/empty_py3_env/lib/python3.6/site-packages/chaco/contour_poly_plot.py", line 46, in _render
    self._update_polys()
  File "/Users/rahulporuri/.edm/envs/empty_py3_env/lib/python3.6/site-packages/chaco/contour_poly_plot.py", line 86, in _update_polys
    c = Cntr(xg, yg, data, ~mask)
ValueError: Arguments x, y, z, mask (if present) must have the same dimensions.
Traceback (most recent call last):
  File "/Users/rahulporuri/.edm/envs/empty_py3_env/lib/python3.6/site-packages/enable/qt4/base_window.py", line 198, in paintEvent
    self.handler.paintEvent(event)
  File "/Users/rahulporuri/.edm/envs/empty_py3_env/lib/python3.6/site-packages/enable/qt4/base_window.py", line 50, in paintEvent
    self._enable_window._paint(event)
  File "/Users/rahulporuri/.edm/envs/empty_py3_env/lib/python3.6/site-packages/enable/abstract_window.py", line 468, in _paint
    self.component.draw(gc, view_bounds=(0, 0, size[0], size[1]))
  File "/Users/rahulporuri/.edm/envs/empty_py3_env/lib/python3.6/site-packages/enable/component.py", line 424, in draw
    self._draw(gc, view_bounds, mode)
  File "/Users/rahulporuri/.edm/envs/empty_py3_env/lib/python3.6/site-packages/enable/component.py", line 776, in _draw
    self._dispatch_draw(layer, gc, view_bounds, mode)
  File "/Users/rahulporuri/.edm/envs/empty_py3_env/lib/python3.6/site-packages/enable/container.py", line 272, in _dispatch_draw
    component._dispatch_draw(layer, gc, new_bounds, mode)
  File "/Users/rahulporuri/.edm/envs/empty_py3_env/lib/python3.6/site-packages/enable/container.py", line 270, in _dispatch_draw
    component._draw(gc, new_bounds, mode)
  File "/Users/rahulporuri/.edm/envs/empty_py3_env/lib/python3.6/site-packages/enable/component.py", line 766, in _draw
    self._dispatch_draw(layer, bb, view_bounds, mode)
  File "/Users/rahulporuri/.edm/envs/empty_py3_env/lib/python3.6/site-packages/enable/container.py", line 272, in _dispatch_draw
    component._dispatch_draw(layer, gc, new_bounds, mode)
  File "/Users/rahulporuri/.edm/envs/empty_py3_env/lib/python3.6/site-packages/enable/component.py", line 796, in _dispatch_draw
    handler(gc, view_bounds, mode)
  File "/Users/rahulporuri/.edm/envs/empty_py3_env/lib/python3.6/site-packages/chaco/base_2d_plot.py", line 204, in _draw_image
    self._render(gc)
  File "/Users/rahulporuri/.edm/envs/empty_py3_env/lib/python3.6/site-packages/chaco/contour_poly_plot.py", line 46, in _render
    self._update_polys()
  File "/Users/rahulporuri/.edm/envs/empty_py3_env/lib/python3.6/site-packages/chaco/contour_poly_plot.py", line 86, in _update_polys
    c = Cntr(xg, yg, data, ~mask)
ValueError: Arguments x, y, z, mask (if present) must have the same dimensions.
Traceback (most recent call last):
  File "/Users/rahulporuri/.edm/envs/empty_py3_env/lib/python3.6/site-packages/enable/qt4/base_window.py", line 198, in paintEvent
    self.handler.paintEvent(event)
  File "/Users/rahulporuri/.edm/envs/empty_py3_env/lib/python3.6/site-packages/enable/qt4/base_window.py", line 50, in paintEvent
    self._enable_window._paint(event)
  File "/Users/rahulporuri/.edm/envs/empty_py3_env/lib/python3.6/site-packages/enable/abstract_window.py", line 468, in _paint
    self.component.draw(gc, view_bounds=(0, 0, size[0], size[1]))
  File "/Users/rahulporuri/.edm/envs/empty_py3_env/lib/python3.6/site-packages/enable/component.py", line 424, in draw
    self._draw(gc, view_bounds, mode)
  File "/Users/rahulporuri/.edm/envs/empty_py3_env/lib/python3.6/site-packages/enable/component.py", line 776, in _draw
    self._dispatch_draw(layer, gc, view_bounds, mode)
  File "/Users/rahulporuri/.edm/envs/empty_py3_env/lib/python3.6/site-packages/enable/container.py", line 272, in _dispatch_draw
    component._dispatch_draw(layer, gc, new_bounds, mode)
  File "/Users/rahulporuri/.edm/envs/empty_py3_env/lib/python3.6/site-packages/enable/container.py", line 270, in _dispatch_draw
    component._draw(gc, new_bounds, mode)
  File "/Users/rahulporuri/.edm/envs/empty_py3_env/lib/python3.6/site-packages/enable/component.py", line 766, in _draw
    self._dispatch_draw(layer, bb, view_bounds, mode)
  File "/Users/rahulporuri/.edm/envs/empty_py3_env/lib/python3.6/site-packages/enable/container.py", line 272, in _dispatch_draw
    component._dispatch_draw(layer, gc, new_bounds, mode)
  File "/Users/rahulporuri/.edm/envs/empty_py3_env/lib/python3.6/site-packages/enable/component.py", line 796, in _dispatch_draw
    handler(gc, view_bounds, mode)
  File "/Users/rahulporuri/.edm/envs/empty_py3_env/lib/python3.6/site-packages/chaco/base_2d_plot.py", line 204, in _draw_image
    self._render(gc)
  File "/Users/rahulporuri/.edm/envs/empty_py3_env/lib/python3.6/site-packages/chaco/contour_poly_plot.py", line 46, in _render
    self._update_polys()
  File "/Users/rahulporuri/.edm/envs/empty_py3_env/lib/python3.6/site-packages/chaco/contour_poly_plot.py", line 86, in _update_polys
    c = Cntr(xg, yg, data, ~mask)
ValueError: Arguments x, y, z, mask (if present) must have the same dimensions.
```


Discussion:
change line 83-84
```python
self.xs = linspace(self.min_x, self.max_x, self.npts_x+1)
self.ys = linspace(self.min_y, self.max_y, self.npts_y+1)
```
to

```python
self.xs = linspace(self.min_x, self.max_x, self.npts_x)
self.ys = linspace(self.min_y, self.max_y, self.npts_y)
```
@slarke Thanks for recommendation. Would you have time to make a PR?

Resolving patch:
diff --git a/examples/demo/advanced/scalar_image_function_inspector.py b/examples/demo/advanced/scalar_image_function_inspector.py
--- a/examples/demo/advanced/scalar_image_function_inspector.py
+++ b/examples/demo/advanced/scalar_image_function_inspector.py
@@ -87,21 +87,32 @@ def compute_model(self):
         # is located at cell centers, so use halfsteps from the
         # min/max values (which are edges)
         xstep = (self.max_x - self.min_x) / self.npts_x
-        #ystep = (self.max_y - self.min_y) / self.npts_y
-        gridx = linspace(self.min_x+xstep/2, self.max_x-xstep/2, self.npts_x)
-        gridy = linspace(self.min_y+xstep/2, self.max_y-xstep/2, self.npts_y)
+        ystep = (self.max_y - self.min_y) / self.npts_y
+        gridx = linspace(self.min_x+xstep/2, self.max_x-xstep/2, self.npts_x+1)
+        gridy = linspace(self.min_y+ystep/2, self.max_y-ystep/2, self.npts_y+1)
         x, y = meshgrid(gridx, gridy)
+
+        d = dict(x=x, y=y)
+        exec("from scipy import *", d)
+        exec("from scipy.special import *", d)
         try:
-            d = dict(x=x, y=y)
-            exec("from scipy import *", d)
-            exec("from scipy.special import *", d)
             self.zs = eval(self.function, d)
+        except NameError:
+            # Raised if the function(s) is not available in scipy context (d)
+            print("The function name {0} is invalid".format(self.function))
+            self.trait_setq(_function=self.function)
+        except SyntaxError:
+            print("The function signature is not valid Python syntax")
+            self.trait_setq(_function=self.function)
+        except Exception as e:
+            err_msg = "The following error occured when using the function {}"
+            print(err_msg.format(e))
+            self.trait_setq(_function=self.function)
+        else:
             self.minz = nanmin(self.zs)
             self.maxz = nanmax(self.zs)
             self.model_changed = True
             self._function = self.function
-        except:
-            self.trait_setq(function=self._function)
 
     def _anytrait_changed(self, name, value):
         if name in ['function', 'npts_x', 'npts_y',


Test patch: