Memory leak related to Chaco back buffering.

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Memory leak related to Chaco back buffering.

Jordan Ilott
Hello all,

I've discovered a memory leak when using back-buffering in Chaco. It would appear that there is a problem with the qpainter and qimage graphics contexts in Enable. The code below demonstrates the problem. It is a simple modification of a demo to use enable.qt4.qpainter instead of the Agg context. I've observed the same problem when using a qimage context. To see the problem, observe the memory consumption in for example, the windows task manager while resizing the window. I am using Pyside if that makes a difference.

I want to use the Qt graphics contexts for consistency in my application. I also use the qpainter contexts to support rendering to images and PDFs. The plots look different when using Agg contexts instead of Qt.



Jordan

"""
Example of how to directly embed Chaco into Qt widgets.

The actual plot being created is drawn from the basic/line_plot1.py code.
"""
from traits.etsconfig.etsconfig import ETSConfig
ETSConfig.toolkit = "qt4"

from numpy import linspace
from scipy.special import jn
from pyface.qt import QtGui
from pyface.util.guisupport import get_app_qt4, start_event_loop_qt4

#***HERE IS THE CHANGE
#from enable.api import Window
from enable.qt4.qpainter import Window
#***THE REST IS UNCHANGED.

from chaco.api import ArrayPlotData, Plot
from chaco.tools.api import PanTool, ZoomTool


def create_chaco_plot(parent):
    x = linspace(-2.0, 10.0, 100)
    pd = ArrayPlotData(index = x)
    for i in range(5):
        pd.set_data("y" + str(i), jn(i,x))

    # Create some line plots of some of the data
    plot = Plot(pd, title="Line Plot", padding=50, border_visible=True, use_backbuffer = True)
    plot.legend.visible = True
    plot.plot(("index", "y0", "y1", "y2"), name="j_n, n<3", color="red")
    plot.plot(("index", "y3"), name="j_3", color="blue")

    # Attach some tools to the plot
    plot.tools.append(PanTool(plot))
    zoom = ZoomTool(component=plot, tool_mode="box", always_on=False)
    plot.overlays.append(zoom)

    # This Window object bridges the Enable and Qt4 worlds, and handles events
    # and drawing.  We can create whatever hierarchy of nested containers we
    # want, as long as the top-level item gets set as the .component attribute
    # of a Window.
    return Window(parent, -1, component=plot)


def main():
    app = get_app_qt4()
    main_window = QtGui.QMainWindow()
    main_window.resize(500,500)

    enable_window = create_chaco_plot(main_window)

    # The .control attribute references a QWidget that gives Chaco events
    # and that Chaco paints into.
    main_window.setCentralWidget(enable_window.control)

    main_window.show()
    start_event_loop_qt4(app)
    return main_window


if __name__ == "__main__":
    # Save window so that it doesn't get garbage collected when run within
    # existing event loop (i.e. from ipython).
    window = main()


_______________________________________________
Enthought-Dev mailing list
[hidden email]
https://mail.enthought.com/mailman/listinfo/enthought-dev
Reply | Threaded
Open this post in threaded view
|

Re: Memory leak related to Chaco back buffering.

Jordan Ilott-2
The same effect may be observed by more correctly specifying the toolkit as below:

from traits.etsconfig.etsconfig import ETSConfig
ETSConfig.toolkit = "qt4.qpainter"

The above code with the more typical:
#from enable.api import Window

Rather than the specific import:
from enable.qt4.qpainter import Window


will give the same result. If the qt4.image toolkit is specified, the problem is not observed.




On Tue, Oct 15, 2013 at 5:22 PM, Jordan Ilott <[hidden email]> wrote:
Hello all,

I've discovered a memory leak when using back-buffering in Chaco. It would appear that there is a problem with the qpainter and qimage graphics contexts in Enable. The code below demonstrates the problem. It is a simple modification of a demo to use enable.qt4.qpainter instead of the Agg context. I've observed the same problem when using a qimage context. To see the problem, observe the memory consumption in for example, the windows task manager while resizing the window. I am using Pyside if that makes a difference.

I want to use the Qt graphics contexts for consistency in my application. I also use the qpainter contexts to support rendering to images and PDFs. The plots look different when using Agg contexts instead of Qt.



Jordan

"""
Example of how to directly embed Chaco into Qt widgets.

The actual plot being created is drawn from the basic/line_plot1.py code.
"""
from traits.etsconfig.etsconfig import ETSConfig
ETSConfig.toolkit = "qt4"

from numpy import linspace
from scipy.special import jn
from pyface.qt import QtGui
from pyface.util.guisupport import get_app_qt4, start_event_loop_qt4

#***HERE IS THE CHANGE
#from enable.api import Window
from enable.qt4.qpainter import Window
#***THE REST IS UNCHANGED.

from chaco.api import ArrayPlotData, Plot
from chaco.tools.api import PanTool, ZoomTool


def create_chaco_plot(parent):
    x = linspace(-2.0, 10.0, 100)
    pd = ArrayPlotData(index = x)
    for i in range(5):
        pd.set_data("y" + str(i), jn(i,x))

    # Create some line plots of some of the data
    plot = Plot(pd, title="Line Plot", padding=50, border_visible=True, use_backbuffer = True)
    plot.legend.visible = True
    plot.plot(("index", "y0", "y1", "y2"), name="j_n, n<3", color="red")
    plot.plot(("index", "y3"), name="j_3", color="blue")

    # Attach some tools to the plot
    plot.tools.append(PanTool(plot))
    zoom = ZoomTool(component=plot, tool_mode="box", always_on=False)
    plot.overlays.append(zoom)

    # This Window object bridges the Enable and Qt4 worlds, and handles events
    # and drawing.  We can create whatever hierarchy of nested containers we
    # want, as long as the top-level item gets set as the .component attribute
    # of a Window.
    return Window(parent, -1, component=plot)


def main():
    app = get_app_qt4()
    main_window = QtGui.QMainWindow()
    main_window.resize(500,500)

    enable_window = create_chaco_plot(main_window)

    # The .control attribute references a QWidget that gives Chaco events
    # and that Chaco paints into.
    main_window.setCentralWidget(enable_window.control)

    main_window.show()
    start_event_loop_qt4(app)
    return main_window


if __name__ == "__main__":
    # Save window so that it doesn't get garbage collected when run within
    # existing event loop (i.e. from ipython).
    window = main()



_______________________________________________
Enthought-Dev mailing list
[hidden email]
https://mail.enthought.com/mailman/listinfo/enthought-dev
Reply | Threaded
Open this post in threaded view
|

Re: Memory leak related to Chaco back buffering.

Jonathan Rocher
Thanks Jordan for reporting the issue. I am able to reproduce it when I interact with the plot. The mem usage goes up by about 1MB each time I zoom in or out. Panning increases the mem usage by a lot each time. I am also getting a segfault 11 on close of the window (details below). Do you get it as well?

Jonathan

Exception Type:  EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x0000000000000048

VM Regions Near 0x48:
--> 
    __TEXT                 0000000100000000-0000000100003000 [   12K] r-x/rwx SM=COW  /Users/USER/Library/Enthought/*/Python.app/Contents/MacOS/Python

Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0   org.python.python             0x00000001000d3dde PyErr_Occurred + 14
1   QtGui.so                       0x000000010796a180 QPixmapWrapper::devType() const + 48
2   QtGui                         0x000000010864f043 QCoreGraphicsPaintEngine::end() + 19
3   QtGui                         0x000000010858ba16 QPainter::end() + 374
4   QtGui.so                       0x00000001079433b0 Sbk_QPainterFunc_end + 160
5   org.python.python             0x00000001000c4587 PyEval_EvalFrameEx + 24759
6   org.python.python             0x00000001000c6a19 PyEval_EvalCodeEx + 2137
7   org.python.python             0x0000000100040200 function_call + 176
8   org.python.python             0x000000010000ead2 PyObject_Call + 98
9   org.python.python             0x00000001000210eb instancemethod_call + 363
10  org.python.python             0x000000010000ead2 PyObject_Call + 98
11  org.python.python             0x00000001000bd217 PyEval_CallObjectWithKeywords + 87
12  org.python.python             0x0000000100084b0e slot_tp_del + 126
13  org.python.python             0x000000010007504d subtype_dealloc + 381
14  org.python.python             0x000000010005604b dict_dealloc + 155
15  ctraits.so                     0x00000001094e7ff7 has_traits_clear + 151
16  org.python.python             0x00000001001043e8 collect + 1464
17  org.python.python             0x0000000100104a14 PyGC_Collect + 52
18  org.python.python             0x00000001000eb1c3 Py_Finalize + 259
19  org.python.python             0x0000000100102b44 Py_Main + 2020
20  org.python.python             0x00000001000026c4 0x100000000 + 9924
21  org.python.python             0x0000000100001c74 0x100000000 + 7284



On Wed, Oct 16, 2013 at 7:50 AM, Jordan Ilott <[hidden email]> wrote:
The same effect may be observed by more correctly specifying the toolkit as below:

from traits.etsconfig.etsconfig import ETSConfig
ETSConfig.toolkit = "qt4.qpainter"

The above code with the more typical:
#from enable.api import Window

Rather than the specific import:
from enable.qt4.qpainter import Window


will give the same result. If the qt4.image toolkit is specified, the problem is not observed.




On Tue, Oct 15, 2013 at 5:22 PM, Jordan Ilott <[hidden email]> wrote:
Hello all,

I've discovered a memory leak when using back-buffering in Chaco. It would appear that there is a problem with the qpainter and qimage graphics contexts in Enable. The code below demonstrates the problem. It is a simple modification of a demo to use enable.qt4.qpainter instead of the Agg context. I've observed the same problem when using a qimage context. To see the problem, observe the memory consumption in for example, the windows task manager while resizing the window. I am using Pyside if that makes a difference.

I want to use the Qt graphics contexts for consistency in my application. I also use the qpainter contexts to support rendering to images and PDFs. The plots look different when using Agg contexts instead of Qt.



Jordan

"""
Example of how to directly embed Chaco into Qt widgets.

The actual plot being created is drawn from the basic/line_plot1.py code.
"""
from traits.etsconfig.etsconfig import ETSConfig
ETSConfig.toolkit = "qt4"

from numpy import linspace
from scipy.special import jn
from pyface.qt import QtGui
from pyface.util.guisupport import get_app_qt4, start_event_loop_qt4

#***HERE IS THE CHANGE
#from enable.api import Window
from enable.qt4.qpainter import Window
#***THE REST IS UNCHANGED.

from chaco.api import ArrayPlotData, Plot
from chaco.tools.api import PanTool, ZoomTool


def create_chaco_plot(parent):
    x = linspace(-2.0, 10.0, 100)
    pd = ArrayPlotData(index = x)
    for i in range(5):
        pd.set_data("y" + str(i), jn(i,x))

    # Create some line plots of some of the data
    plot = Plot(pd, title="Line Plot", padding=50, border_visible=True, use_backbuffer = True)
    plot.legend.visible = True
    plot.plot(("index", "y0", "y1", "y2"), name="j_n, n<3", color="red")
    plot.plot(("index", "y3"), name="j_3", color="blue")

    # Attach some tools to the plot
    plot.tools.append(PanTool(plot))
    zoom = ZoomTool(component=plot, tool_mode="box", always_on=False)
    plot.overlays.append(zoom)

    # This Window object bridges the Enable and Qt4 worlds, and handles events
    # and drawing.  We can create whatever hierarchy of nested containers we
    # want, as long as the top-level item gets set as the .component attribute
    # of a Window.
    return Window(parent, -1, component=plot)


def main():
    app = get_app_qt4()
    main_window = QtGui.QMainWindow()
    main_window.resize(500,500)

    enable_window = create_chaco_plot(main_window)

    # The .control attribute references a QWidget that gives Chaco events
    # and that Chaco paints into.
    main_window.setCentralWidget(enable_window.control)

    main_window.show()
    start_event_loop_qt4(app)
    return main_window


if __name__ == "__main__":
    # Save window so that it doesn't get garbage collected when run within
    # existing event loop (i.e. from ipython).
    window = main()



_______________________________________________
Enthought-Dev mailing list
[hidden email]
https://mail.enthought.com/mailman/listinfo/enthought-dev




--
Jonathan Rocher, PhD
Scientific software developer
Enthought, Inc.
[hidden email]
1-512-536-1057
http://www.enthought.com


_______________________________________________
Enthought-Dev mailing list
[hidden email]
https://mail.enthought.com/mailman/listinfo/enthought-dev
Reply | Threaded
Open this post in threaded view
|

Re: Memory leak related to Chaco back buffering.

Jordan Ilott-2
Well, I think I may have chased this down to either a general Qt problem or a PySide problem. If the Kiva QPainter backend is modified to remove a single
call to: QPainter.device, the problem goes away. So, rather than

pixmap = img.gc.device() in kiva.qpainter.draw_image

using: pixmap = img.qt_dc

appears to solve the problem. It may be reasonable to just use this work around since it doesn't appear that the primary reason to call QPainter.device() is considered. In the case that the painter is not active, QPainter.device() will return 0 rather than a Pixmap object.

Can someone who uses PyQT verify if the problem can be observed? It may be PySide specific.




On Wed, Oct 16, 2013 at 9:44 AM, Jonathan Rocher <[hidden email]> wrote:
Thanks Jordan for reporting the issue. I am able to reproduce it when I interact with the plot. The mem usage goes up by about 1MB each time I zoom in or out. Panning increases the mem usage by a lot each time. I am also getting a segfault 11 on close of the window (details below). Do you get it as well?

Jonathan

Exception Type:  EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x0000000000000048

VM Regions Near 0x48:
--> 
    __TEXT                 0000000100000000-0000000100003000 [   12K] r-x/rwx SM=COW  /Users/USER/Library/Enthought/*/Python.app/Contents/MacOS/Python

Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0   org.python.python             0x00000001000d3dde PyErr_Occurred + 14
1   QtGui.so                       0x000000010796a180 QPixmapWrapper::devType() const + 48
2   QtGui                         0x000000010864f043 QCoreGraphicsPaintEngine::end() + 19
3   QtGui                         0x000000010858ba16 QPainter::end() + 374
4   QtGui.so                       0x00000001079433b0 Sbk_QPainterFunc_end + 160
5   org.python.python             0x00000001000c4587 PyEval_EvalFrameEx + 24759
6   org.python.python             0x00000001000c6a19 PyEval_EvalCodeEx + 2137
7   org.python.python             0x0000000100040200 function_call + 176
8   org.python.python             0x000000010000ead2 PyObject_Call + 98
9   org.python.python             0x00000001000210eb instancemethod_call + 363
10  org.python.python             0x000000010000ead2 PyObject_Call + 98
11  org.python.python             0x00000001000bd217 PyEval_CallObjectWithKeywords + 87
12  org.python.python             0x0000000100084b0e slot_tp_del + 126
13  org.python.python             0x000000010007504d subtype_dealloc + 381
14  org.python.python             0x000000010005604b dict_dealloc + 155
15  ctraits.so                     0x00000001094e7ff7 has_traits_clear + 151
16  org.python.python             0x00000001001043e8 collect + 1464
17  org.python.python             0x0000000100104a14 PyGC_Collect + 52
18  org.python.python             0x00000001000eb1c3 Py_Finalize + 259
19  org.python.python             0x0000000100102b44 Py_Main + 2020
20  org.python.python             0x00000001000026c4 0x100000000 + 9924
21  org.python.python             0x0000000100001c74 0x100000000 + 7284



On Wed, Oct 16, 2013 at 7:50 AM, Jordan Ilott <[hidden email]> wrote:
The same effect may be observed by more correctly specifying the toolkit as below:

from traits.etsconfig.etsconfig import ETSConfig
ETSConfig.toolkit = "qt4.qpainter"

The above code with the more typical:
#from enable.api import Window

Rather than the specific import:
from enable.qt4.qpainter import Window


will give the same result. If the qt4.image toolkit is specified, the problem is not observed.




On Tue, Oct 15, 2013 at 5:22 PM, Jordan Ilott <[hidden email]> wrote:
Hello all,

I've discovered a memory leak when using back-buffering in Chaco. It would appear that there is a problem with the qpainter and qimage graphics contexts in Enable. The code below demonstrates the problem. It is a simple modification of a demo to use enable.qt4.qpainter instead of the Agg context. I've observed the same problem when using a qimage context. To see the problem, observe the memory consumption in for example, the windows task manager while resizing the window. I am using Pyside if that makes a difference.

I want to use the Qt graphics contexts for consistency in my application. I also use the qpainter contexts to support rendering to images and PDFs. The plots look different when using Agg contexts instead of Qt.



Jordan

"""
Example of how to directly embed Chaco into Qt widgets.

The actual plot being created is drawn from the basic/line_plot1.py code.
"""
from traits.etsconfig.etsconfig import ETSConfig
ETSConfig.toolkit = "qt4"

from numpy import linspace
from scipy.special import jn
from pyface.qt import QtGui
from pyface.util.guisupport import get_app_qt4, start_event_loop_qt4

#***HERE IS THE CHANGE
#from enable.api import Window
from enable.qt4.qpainter import Window
#***THE REST IS UNCHANGED.

from chaco.api import ArrayPlotData, Plot
from chaco.tools.api import PanTool, ZoomTool


def create_chaco_plot(parent):
    x = linspace(-2.0, 10.0, 100)
    pd = ArrayPlotData(index = x)
    for i in range(5):
        pd.set_data("y" + str(i), jn(i,x))

    # Create some line plots of some of the data
    plot = Plot(pd, title="Line Plot", padding=50, border_visible=True, use_backbuffer = True)
    plot.legend.visible = True
    plot.plot(("index", "y0", "y1", "y2"), name="j_n, n<3", color="red")
    plot.plot(("index", "y3"), name="j_3", color="blue")

    # Attach some tools to the plot
    plot.tools.append(PanTool(plot))
    zoom = ZoomTool(component=plot, tool_mode="box", always_on=False)
    plot.overlays.append(zoom)

    # This Window object bridges the Enable and Qt4 worlds, and handles events
    # and drawing.  We can create whatever hierarchy of nested containers we
    # want, as long as the top-level item gets set as the .component attribute
    # of a Window.
    return Window(parent, -1, component=plot)


def main():
    app = get_app_qt4()
    main_window = QtGui.QMainWindow()
    main_window.resize(500,500)

    enable_window = create_chaco_plot(main_window)

    # The .control attribute references a QWidget that gives Chaco events
    # and that Chaco paints into.
    main_window.setCentralWidget(enable_window.control)

    main_window.show()
    start_event_loop_qt4(app)
    return main_window


if __name__ == "__main__":
    # Save window so that it doesn't get garbage collected when run within
    # existing event loop (i.e. from ipython).
    window = main()



_______________________________________________
Enthought-Dev mailing list
[hidden email]
https://mail.enthought.com/mailman/listinfo/enthought-dev




--
Jonathan Rocher, PhD
Scientific software developer
Enthought, Inc.
[hidden email]
<a href="tel:1-512-536-1057" value="+15125361057" target="_blank">1-512-536-1057
http://www.enthought.com


_______________________________________________
Enthought-Dev mailing list
[hidden email]
https://mail.enthought.com/mailman/listinfo/enthought-dev



_______________________________________________
Enthought-Dev mailing list
[hidden email]
https://mail.enthought.com/mailman/listinfo/enthought-dev
Reply | Threaded
Open this post in threaded view
|

Re: Memory leak related to Chaco back buffering.

Jordan Ilott-2
I've submitted a pull request that I think is an effective workaround. In my tests, I haven't observed any problems using it.

Jordan


On Wed, Oct 16, 2013 at 9:47 AM, Jordan Ilott <[hidden email]> wrote:
Well, I think I may have chased this down to either a general Qt problem or a PySide problem. If the Kiva QPainter backend is modified to remove a single
call to: QPainter.device, the problem goes away. So, rather than

pixmap = img.gc.device() in kiva.qpainter.draw_image

using: pixmap = img.qt_dc

appears to solve the problem. It may be reasonable to just use this work around since it doesn't appear that the primary reason to call QPainter.device() is considered. In the case that the painter is not active, QPainter.device() will return 0 rather than a Pixmap object.

Can someone who uses PyQT verify if the problem can be observed? It may be PySide specific.




On Wed, Oct 16, 2013 at 9:44 AM, Jonathan Rocher <[hidden email]> wrote:
Thanks Jordan for reporting the issue. I am able to reproduce it when I interact with the plot. The mem usage goes up by about 1MB each time I zoom in or out. Panning increases the mem usage by a lot each time. I am also getting a segfault 11 on close of the window (details below). Do you get it as well?

Jonathan

Exception Type:  EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x0000000000000048

VM Regions Near 0x48:
--> 
    __TEXT                 0000000100000000-0000000100003000 [   12K] r-x/rwx SM=COW  /Users/USER/Library/Enthought/*/Python.app/Contents/MacOS/Python

Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0   org.python.python             0x00000001000d3dde PyErr_Occurred + 14
1   QtGui.so                       0x000000010796a180 QPixmapWrapper::devType() const + 48
2   QtGui                         0x000000010864f043 QCoreGraphicsPaintEngine::end() + 19
3   QtGui                         0x000000010858ba16 QPainter::end() + 374
4   QtGui.so                       0x00000001079433b0 Sbk_QPainterFunc_end + 160
5   org.python.python             0x00000001000c4587 PyEval_EvalFrameEx + 24759
6   org.python.python             0x00000001000c6a19 PyEval_EvalCodeEx + 2137
7   org.python.python             0x0000000100040200 function_call + 176
8   org.python.python             0x000000010000ead2 PyObject_Call + 98
9   org.python.python             0x00000001000210eb instancemethod_call + 363
10  org.python.python             0x000000010000ead2 PyObject_Call + 98
11  org.python.python             0x00000001000bd217 PyEval_CallObjectWithKeywords + 87
12  org.python.python             0x0000000100084b0e slot_tp_del + 126
13  org.python.python             0x000000010007504d subtype_dealloc + 381
14  org.python.python             0x000000010005604b dict_dealloc + 155
15  ctraits.so                     0x00000001094e7ff7 has_traits_clear + 151
16  org.python.python             0x00000001001043e8 collect + 1464
17  org.python.python             0x0000000100104a14 PyGC_Collect + 52
18  org.python.python             0x00000001000eb1c3 Py_Finalize + 259
19  org.python.python             0x0000000100102b44 Py_Main + 2020
20  org.python.python             0x00000001000026c4 0x100000000 + 9924
21  org.python.python             0x0000000100001c74 0x100000000 + 7284



On Wed, Oct 16, 2013 at 7:50 AM, Jordan Ilott <[hidden email]> wrote:
The same effect may be observed by more correctly specifying the toolkit as below:

from traits.etsconfig.etsconfig import ETSConfig
ETSConfig.toolkit = "qt4.qpainter"

The above code with the more typical:
#from enable.api import Window

Rather than the specific import:
from enable.qt4.qpainter import Window


will give the same result. If the qt4.image toolkit is specified, the problem is not observed.




On Tue, Oct 15, 2013 at 5:22 PM, Jordan Ilott <[hidden email]> wrote:
Hello all,

I've discovered a memory leak when using back-buffering in Chaco. It would appear that there is a problem with the qpainter and qimage graphics contexts in Enable. The code below demonstrates the problem. It is a simple modification of a demo to use enable.qt4.qpainter instead of the Agg context. I've observed the same problem when using a qimage context. To see the problem, observe the memory consumption in for example, the windows task manager while resizing the window. I am using Pyside if that makes a difference.

I want to use the Qt graphics contexts for consistency in my application. I also use the qpainter contexts to support rendering to images and PDFs. The plots look different when using Agg contexts instead of Qt.



Jordan

"""
Example of how to directly embed Chaco into Qt widgets.

The actual plot being created is drawn from the basic/line_plot1.py code.
"""
from traits.etsconfig.etsconfig import ETSConfig
ETSConfig.toolkit = "qt4"

from numpy import linspace
from scipy.special import jn
from pyface.qt import QtGui
from pyface.util.guisupport import get_app_qt4, start_event_loop_qt4

#***HERE IS THE CHANGE
#from enable.api import Window
from enable.qt4.qpainter import Window
#***THE REST IS UNCHANGED.

from chaco.api import ArrayPlotData, Plot
from chaco.tools.api import PanTool, ZoomTool


def create_chaco_plot(parent):
    x = linspace(-2.0, 10.0, 100)
    pd = ArrayPlotData(index = x)
    for i in range(5):
        pd.set_data("y" + str(i), jn(i,x))

    # Create some line plots of some of the data
    plot = Plot(pd, title="Line Plot", padding=50, border_visible=True, use_backbuffer = True)
    plot.legend.visible = True
    plot.plot(("index", "y0", "y1", "y2"), name="j_n, n<3", color="red")
    plot.plot(("index", "y3"), name="j_3", color="blue")

    # Attach some tools to the plot
    plot.tools.append(PanTool(plot))
    zoom = ZoomTool(component=plot, tool_mode="box", always_on=False)
    plot.overlays.append(zoom)

    # This Window object bridges the Enable and Qt4 worlds, and handles events
    # and drawing.  We can create whatever hierarchy of nested containers we
    # want, as long as the top-level item gets set as the .component attribute
    # of a Window.
    return Window(parent, -1, component=plot)


def main():
    app = get_app_qt4()
    main_window = QtGui.QMainWindow()
    main_window.resize(500,500)

    enable_window = create_chaco_plot(main_window)

    # The .control attribute references a QWidget that gives Chaco events
    # and that Chaco paints into.
    main_window.setCentralWidget(enable_window.control)

    main_window.show()
    start_event_loop_qt4(app)
    return main_window


if __name__ == "__main__":
    # Save window so that it doesn't get garbage collected when run within
    # existing event loop (i.e. from ipython).
    window = main()



_______________________________________________
Enthought-Dev mailing list
[hidden email]
https://mail.enthought.com/mailman/listinfo/enthought-dev




--
Jonathan Rocher, PhD
Scientific software developer
Enthought, Inc.
[hidden email]
<a href="tel:1-512-536-1057" value="+15125361057" target="_blank">1-512-536-1057
http://www.enthought.com


_______________________________________________
Enthought-Dev mailing list
[hidden email]
https://mail.enthought.com/mailman/listinfo/enthought-dev




_______________________________________________
Enthought-Dev mailing list
[hidden email]
https://mail.enthought.com/mailman/listinfo/enthought-dev