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

Some plot types "hang" on NaN data #373

Open jvkersch opened 7 years ago

jvkersch commented 7 years ago

From discussion offline:

Some plot types (FilledLinePlot and PolygonPlot being the ones that I tested) don’t do well with NaN data. If you try to plot a line or polygon where one of the coordinates is NaN, the application will hang (the NaN gets converted somewhere in Agg to some obscenely large integer, and Agg will keep itself busy trying to draw a line to that faraway location).

@corranwebster's answer: Yes - it would be better to raise a ValueError or something than hang.

Another possibility which would match behaviour of line plots would be to break into runs of non-NaN values and then draw a separate polygon for each. That might give some odd results, though, and would require some re-working of the code.

Final possibility would be to just drop the NaN values silently before calling the rendering code.

@rkern's answer:

Yeah, the Chaco renderers have the responsibility of cleaning the data of non-finite (or even just out-of-bbox) data before creating the view-space coordinates that are given to the GC. It's mostly obvious how to do that for lines and points, but a little less obvious how to do that for polygons, so I suspect a simple sin of omission there.

The _gather_points() method is typically where this is done.


The code below will hang:

import numpy as np

from enable.api import Component, ComponentEditor
from traits.api import HasStrictTraits, Instance
from traitsui.api import UItem, View
from chaco.api import ArrayPlotData, Plot

class Demo(HasStrictTraits):

    view = View(UItem('plot', editor=ComponentEditor()))
    plot = Instance(Component)

    def _plot_default(self):
        edges = np.linspace(0, 1, 10)
        hist = np.full(edges.shape[0], 0)
        hist[5] = np.nan

        plot_data = ArrayPlotData(hh_hist=hist, hh_edges=edges)
        plot = Plot(plot_data)
        plot.plot(
            ('hh_edges', 'hh_hist'),
            type='filled_line',
            render_style='connectedhold',
            fill_color='black',
            alpha=0.5,
        )
        return plot

if __name__ == '__main__':
    Demo().configure_traits()

OS, Python version: Tested under Python 2.7 on Mac OS X 10.11 and Linux (Ubuntu 14.04)

aaronayres35 commented 3 years ago

Running the given code I now see the following immediate failure:

Traceback (most recent call last):
  File "examples/demo/junk.py", line 32, in <module>
    Demo().configure_traits()
  File "/Users/aayres/Desktop/traits/traits/has_traits.py", line 2095, in configure_traits
    args,
  File "/Users/aayres/.edm/envs/chaco-test-3.6-pyqt5/lib/python3.6/site-packages/traitsui/qt4/toolkit.py", line 233, in view_application
    context, view, kind, handler, id, scrollable, args
  File "/Users/aayres/.edm/envs/chaco-test-3.6-pyqt5/lib/python3.6/site-packages/traitsui/qt4/view_application.py", line 84, in view_application
    context, view, kind, handler, id, scrollable, args
  File "/Users/aayres/.edm/envs/chaco-test-3.6-pyqt5/lib/python3.6/site-packages/traitsui/qt4/view_application.py", line 126, in __init__
    args=self.args,
  File "/Users/aayres/.edm/envs/chaco-test-3.6-pyqt5/lib/python3.6/site-packages/traitsui/view.py", line 462, in ui
    ui.ui(parent, kind)
  File "/Users/aayres/.edm/envs/chaco-test-3.6-pyqt5/lib/python3.6/site-packages/traitsui/ui.py", line 244, in ui
    self.rebuild(self, parent)
  File "/Users/aayres/.edm/envs/chaco-test-3.6-pyqt5/lib/python3.6/site-packages/traitsui/qt4/toolkit.py", line 163, in ui_live
    ui_live.ui_live(ui, parent)
  File "/Users/aayres/.edm/envs/chaco-test-3.6-pyqt5/lib/python3.6/site-packages/traitsui/qt4/ui_live.py", line 43, in ui_live
    _ui_dialog(ui, parent, BaseDialog.NONMODAL)
  File "/Users/aayres/.edm/envs/chaco-test-3.6-pyqt5/lib/python3.6/site-packages/traitsui/qt4/ui_live.py", line 65, in _ui_dialog
    BaseDialog.display_ui(ui, parent, style)
  File "/Users/aayres/.edm/envs/chaco-test-3.6-pyqt5/lib/python3.6/site-packages/traitsui/qt4/ui_base.py", line 286, in display_ui
    ui.owner.init(ui, parent, style)
  File "/Users/aayres/.edm/envs/chaco-test-3.6-pyqt5/lib/python3.6/site-packages/traitsui/qt4/ui_live.py", line 225, in init
    self.add_contents(panel(ui), bbox)
  File "/Users/aayres/.edm/envs/chaco-test-3.6-pyqt5/lib/python3.6/site-packages/traitsui/qt4/ui_panel.py", line 259, in panel
    panel = _GroupPanel(content[0], ui).control
  File "/Users/aayres/.edm/envs/chaco-test-3.6-pyqt5/lib/python3.6/site-packages/traitsui/qt4/ui_panel.py", line 617, in __init__
    layout = self._add_items(content, inner)
  File "/Users/aayres/.edm/envs/chaco-test-3.6-pyqt5/lib/python3.6/site-packages/traitsui/qt4/ui_panel.py", line 883, in _add_items
    ui, object, name, item.tooltip, None
  File "/Users/aayres/.edm/envs/chaco-test-3.6-pyqt5/lib/python3.6/site-packages/traitsui/editor_factory.py", line 132, in simple_editor
    description=description,
  File "/Users/aayres/.edm/envs/chaco-test-3.6-pyqt5/lib/python3.6/site-packages/traitsui/editor.py", line 459, in __init__
    self.old_value = getattr(self.object, self.name)
  File "examples/demo/junk.py", line 17, in _plot_default
    hist[5] = np.nan
ValueError: cannot convert float NaN to integer