3

I have an HPlotContainer with 2 empty LinePlots as defaults, created using create_line_plot() factory function. I then perform some calculations and would like to update the plots. How do I access the ArrayPlotData of a LinePlot? I have tried something like container.components[0].data and I got an

AttributeError: 'LinePlot' object has no attribute 'data'

Clearly I am not doing the right thing here.

MindV0rtex
  • 336
  • 1
  • 9

1 Answers1

0

The LinePlot object you are manipulating is actually what Chaco calls a "renderer" and doesn't have access to the data. To update the plots dynamically, you want to call the set_data method on the ArrayPlotData object. You can access that on the Plot objects, but in your case it makes most sense to keep a reference directly to the ArrayPlotData object. If you want to update the LinePlot object then make a reference to it. This example shows the standard way to do that kind of thing with TraitsUI and Chaco:

from chaco.api import ArrayPlotData, HPlotContainer, Plot, LinePlot
from enable.api import ComponentEditor
import numpy as np
from traits.api import Array, Event, HasTraits, Instance, Int
from traitsui.api import ButtonEditor, Item, View


class DataUpdateDemo(HasTraits):
    plots = Instance(HPlotContainer)
    plot_data = Instance(ArrayPlotData)
    line_plot_1 = Instance(LinePlot)
    line_plot_2 = Instance(LinePlot)
    x = Array
    y = Array
    go = Event
    w = Int(1)

    def _x_default(self):
        x = np.linspace(-np.pi, np.pi, 100)
        return x

    def _y_default(self):
        y = np.sin(self.w * self.x)
        return y

    def _plots_default(self):
        self.plot_data = ArrayPlotData(y=self.y, x=self.x)
        plot1 = Plot(self.plot_data)
        self.line_plot_renderer1 = plot1.plot(('x', 'y'), kind='line')[0]
        plot2 = Plot(self.plot_data)
        self.line_plot_renderer_2 = plot2.plot(('y', 'x'), kind='line')[0]
        plots = HPlotContainer(plot1, plot2)
        return plots

    def _go_fired(self):
        self.w += 1
        y = np.sin(self.w * self.x)
        self.plot_data.set_data("y", y)

    traits_view = View(
        Item('plots', editor=ComponentEditor(), show_label=False),
        Item('go', editor=ButtonEditor(label="update"), show_label=False),
    )


if __name__ == "__main__":
    dud = DataUpdateDemo()
    dud.configure_traits()

Now you can do whatever manipulations you want on the LinePlot object.

I get output that looks like this:

enter image description here

Tim D
  • 1,645
  • 1
  • 25
  • 46
  • Well, `Plot` class has a `data` attribute, as you demonstrate yourself, but `LinePlot` seems to not have it. I used `LinePlot` because I found it easier to modify its appearance settings, like axis orientation, etc. – MindV0rtex Nov 25 '15 at 15:27
  • Thanks for the clarification. I have updated the code and explanation. – Tim D Nov 25 '15 at 21:33