dynamically add subplots to figure

Is it possible to add subplots to a figure if I don't know in advance
how many subplots I need to add?

What I do now is I call add_subplot like add_subplot(i, 1, i) where i
is 1 initially, and just increases by 1 on each call. This almost
works. Except the first plot takes up the whole figure, the second
plot is placed on top of the bottom half of the first plot, etc. Is
there a way to "resize" the plots when a subplot is added? Or how
would I "re-plot" the previous subplots?

Thanks.

-Tom

Is it possible to add subplots to a figure if I don't know in advance
how many subplots I need to add?

What I do now is I call add_subplot like add_subplot(i, 1, i) where i
is 1 initially, and just increases by 1 on each call. This almost
works. Except the first plot takes up the whole figure, the second
plot is placed on top of the bottom half of the first plot, etc. Is
there a way to "resize" the plots when a subplot is added? Or how
would I "re-plot" the previous subplots?

See the Axes.change_geometry command

  http://matplotlib.sourceforge.net/api/axes_api.html#matplotlib.axes.SubplotBase.change_geometry

As in this example::

    import matplotlib.pyplot as plt

    # start with one
    fig = plt.figure()
    ax = fig.add_subplot(111)
    ax.plot([1,2,3])

    # now later you get a new subplot; change the geometry of the existing
    n = len(fig.axes)
    for i in range(n):
        fig.axes[i].change_geometry(n+1, 1, i+1)

    # add the new
    ax = fig.add_subplot(n+1, 1, n+1)
    ax.plot([4,5,6])

    plt.show()

JDH

···

On Tue, Jun 2, 2009 at 9:03 AM, Tom Vaughan <tom@...2628...> wrote:

Thanks.

-Tom

------------------------------------------------------------------------------
OpenSolaris 2009.06 is a cutting edge operating system for enterprises
looking to deploy the next generation of Solaris that includes the latest
innovations from Sun and the OpenSource community. Download a copy and
enjoy capabilities such as Networking, Storage and Virtualization.
Go to: http://p.sf.net/sfu/opensolaris-get
_______________________________________________
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
matplotlib-users List Signup and Options

Awesome. Thanks.

Strangely this doesn't quite work for me. Luckily I keep a list of my
subplots. So I do:

        def new_subplot(self):
                nsubplots = len(self.__subplots) + 1

                for i, subplot in enumerate(self.__subplots):
                        subplot.change_geometry(nsubplots, 1, i + 1)

                subplot = self.figure.add_subplot(nsubplots, 1, nsubplots)
                subplot.grid(True)

                self.__subplots.append(subplot)
                self.__subplot = subplot

Interestingly, if I were to 'print dir(self.figure.axes[i])' I can see
the change_geometry attribute, but when I attempt to call it, I am
told "AttributeError: 'AxesSubplot' object has no attribute
'change_geomtry'" This lead me to what I have above.

Thanks.

-Tom

···

On Tue, Jun 2, 2009 at 07:33, John Hunter<jdh2358@...287...> wrote:

On Tue, Jun 2, 2009 at 9:03 AM, Tom Vaughan <tom@...2628...> wrote:

Is it possible to add subplots to a figure if I don't know in advance
how many subplots I need to add?

What I do now is I call add_subplot like add_subplot(i, 1, i) where i
is 1 initially, and just increases by 1 on each call. This almost
works. Except the first plot takes up the whole figure, the second
plot is placed on top of the bottom half of the first plot, etc. Is
there a way to "resize" the plots when a subplot is added? Or how
would I "re-plot" the previous subplots?

See the Axes.change_geometry command

http://matplotlib.sourceforge.net/api/axes_api.html#matplotlib.axes.SubplotBase.change_geometry

As in this example::

import matplotlib.pyplot as plt

# start with one
fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot([1,2,3])

# now later you get a new subplot; change the geometry of the existing
n = len(fig.axes)
for i in range(n):
fig.axes[i].change_geometry(n+1, 1, i+1)

Check your spelling: 'change_geomtry'

···

On Tue, Jun 2, 2009 at 10:18 AM, Tom Vaughan <tom@...2628...> wrote:

Interestingly, if I were to 'print dir(self.figure.axes[i])' I can see
the change_geometry attribute, but when I attempt to call it, I am
told "AttributeError: 'AxesSubplot' object has no attribute
'change_geomtry'" This lead me to what I have above.

Whoops. Thanks.

-Tom

···

On Tue, Jun 2, 2009 at 08:40, John Hunter<jdh2358@...287...> wrote:

On Tue, Jun 2, 2009 at 10:18 AM, Tom Vaughan <tom@...2628...> wrote:

Interestingly, if I were to 'print dir(self.figure.axes[i])' I can see
the change_geometry attribute, but when I attempt to call it, I am
told "AttributeError: 'AxesSubplot' object has no attribute
'change_geomtry'" This lead me to what I have above.

Check your spelling: 'change_geomtry'

To follow-up on this a bit, the second, third, etc subplots all seem
to get stuck with the first subplot's x-axis. Let's say the first plot
is -60 to 60, and the second plot is 2 - 4. The data in the second
plot is plotted on the correct scale (2 to 4), but I still see -60 to
60.

Actually, this isn't entirely correct. When I add a third subplot, the
second subplot becomes correct. So the -60 to 60 only sticks to the
most recently added subplot.

Any ideas?

Thanks.

-Tom

···

On Tue, Jun 2, 2009 at 07:33, John Hunter<jdh2358@...287...> wrote:

On Tue, Jun 2, 2009 at 9:03 AM, Tom Vaughan <tom@...2628...> wrote:

Is it possible to add subplots to a figure if I don't know in advance
how many subplots I need to add?

What I do now is I call add_subplot like add_subplot(i, 1, i) where i
is 1 initially, and just increases by 1 on each call. This almost
works. Except the first plot takes up the whole figure, the second
plot is placed on top of the bottom half of the first plot, etc. Is
there a way to "resize" the plots when a subplot is added? Or how
would I "re-plot" the previous subplots?

See the Axes.change_geometry command

http://matplotlib.sourceforge.net/api/axes_api.html#matplotlib.axes.SubplotBase.change_geometry

post some code

···

On Tue, Jun 2, 2009 at 1:51 PM, Tom Vaughan <tom@...2628...> wrote:

On Tue, Jun 2, 2009 at 07:33, John Hunter<jdh2358@...287...> wrote:

On Tue, Jun 2, 2009 at 9:03 AM, Tom Vaughan <tom@...2628...> wrote:

Is it possible to add subplots to a figure if I don't know in advance
how many subplots I need to add?

What I do now is I call add_subplot like add_subplot(i, 1, i) where i
is 1 initially, and just increases by 1 on each call. This almost
works. Except the first plot takes up the whole figure, the second
plot is placed on top of the bottom half of the first plot, etc. Is
there a way to "resize" the plots when a subplot is added? Or how
would I "re-plot" the previous subplots?

See the Axes.change_geometry command

http://matplotlib.sourceforge.net/api/axes_api.html#matplotlib.axes.SubplotBase.change_geometry

To follow-up on this a bit, the second, third, etc subplots all seem
to get stuck with the first subplot's x-axis. Let's say the first plot
is -60 to 60, and the second plot is 2 - 4. The data in the second
plot is plotted on the correct scale (2 to 4), but I still see -60 to
60.

Actually, this isn't entirely correct. When I add a third subplot, the
second subplot becomes correct. So the -60 to 60 only sticks to the
most recently added subplot.

Any ideas?

I thought this might be required...

We have a variety of telemetry applications that all require some sort
of visual display of data. We've created a widget based upon
matplotlib that can be used stand-alone (reads JSON formatted data
files), or within PyGTK applications and can plot data sets in
"real-time". So the whole thing is excessively complex. I'd be happy
to package up the whole thing if anyone is interested. Currently it
requires the latest Ubuntu release with several additional development
libraries like GLib. What I've posted below is just the abstract plot
widget.

I think the relevant parts are:

                from matplotlib.figure import Figure
                self.figure = Figure()

                self.__subplots =
                self.subplot_new()

                self.__axl = self.figure.gca()
                self.__axl.yaxis.set_label_position('left')
                self.__axl.yaxis.tick_left()

                self.__axr = self.__axl.twinx()
                self.__axr.yaxis.set_label_position('right')
                self.__axr.yaxis.tick_right()

and then:

        def subplot_new(self):
                nsubplots = len(self.__subplots) + 1

                subplot = self.figure.add_subplot(nsubplots, 1, nsubplots)
                subplot.grid(True)

                self.__subplots.append(subplot)
                self.__subplot = subplot

                for i, subplot in enumerate(self.__subplots):
                        subplot.change_geometry(nsubplots, 1, i + 1)

and then:

        def __plot__(self, x, y, style='-', color=0xFF0000,
xlabel=None, ylabel=None):
                IBackend.__plot__(self, x, y, style=style,
color=color, xlabel=xlabel, ylabel=ylabel)

                if xlabel != None:
                        self.__subplot.set_xlabel(xlabel)
                if ylabel != None:
                        self.__subplot.set_ylabel(ylabel)

                self.__subplot.plot(x, y, style, color='#%06X' % (color))
                self.__subplot.grid(True)

        def plotr(self, *args, **kwargs):
                self.figure.sca(self.__axr)
                if not kwargs.has_key('color'):
                        kwargs['color'] = 0x00FF00
                self.__plot__(*args, **kwargs)

        def plotl(self, *args, **kwargs):
                self.figure.sca(self.__axl)
                if not kwargs.has_key('color'):
                        kwargs['color'] = 0xFF0000
                self.__plot__(*args, **kwargs)

The whole thing:

from __future__ import with_statement

# standard python libraries
try:
        import json
except:
        import simplejson as json

import re
import os
import time

# matplotlib.sf.net
import matplotlib
import numpy

# www.gtk.org
import gtk

# our own libraries
from elrond.macros import clamp
from elrond.util import Object, Property

def parse(f):
        x =
        y =

        fd = open(f, 'r')
        lines = [l.strip() for l in fd.readlines()]
        fd.close()

        for i, line in enumerate(lines):
                data = filter(lambda x: x != '', re.split('[, ]', line.strip()))

                try:
                        y.append(float(data[1]))
                        x.append(float(data[0]))
                except IndexError:
                        y.append(float(data[0]))
                        x.append(i)

        return x, y

···

On Tue, Jun 2, 2009 at 11:59, John Hunter<jdh2358@...287...> wrote:

On Tue, Jun 2, 2009 at 1:51 PM, Tom Vaughan <tom@...2628...> wrote:

On Tue, Jun 2, 2009 at 07:33, John Hunter<jdh2358@...287...> wrote:

On Tue, Jun 2, 2009 at 9:03 AM, Tom Vaughan <tom@...2628...> wrote:

Is it possible to add subplots to a figure if I don't know in advance
how many subplots I need to add?

What I do now is I call add_subplot like add_subplot(i, 1, i) where i
is 1 initially, and just increases by 1 on each call. This almost
works. Except the first plot takes up the whole figure, the second
plot is placed on top of the bottom half of the first plot, etc. Is
there a way to "resize" the plots when a subplot is added? Or how
would I "re-plot" the previous subplots?

See the Axes.change_geometry command

http://matplotlib.sourceforge.net/api/axes_api.html#matplotlib.axes.SubplotBase.change_geometry

To follow-up on this a bit, the second, third, etc subplots all seem
to get stuck with the first subplot's x-axis. Let's say the first plot
is -60 to 60, and the second plot is 2 - 4. The data in the second
plot is plotted on the correct scale (2 to 4), but I still see -60 to
60.

Actually, this isn't entirely correct. When I add a third subplot, the
second subplot becomes correct. So the -60 to 60 only sticks to the
most recently added subplot.

Any ideas?

post some code

##
## Backends...
##

class IBackend(Object):
        """The IBackend class is the base implementation for any class
that can produce plots.
        e.g. ASCII art or fancy GUI backends like matplotlib.
        """

        def stripchart(self, filename):
                x_list, y_list = parse(filename)

                self.clear()

                self.props.ymin = 0
                self.props.ymax = 100

                step = 100

                x_first = x_list[0: clamp(step, u=len(x_list))]
                y_first = y_list[0: clamp(step, u=len(y_list))]

                self.props.xmin = 0
                self.props.xmax = len(x_first)

                for i in range(0, len(x_first)):
                        self.plotl(x_first[0:i + 1], y_first[0:i + 1])
                        self.draw()

                self.plotl(x_list, y_list)

                for i in range(0, len(x_list)):
                        self.props.xmin = i + 1
                        self.props.xmax = i + 1 + step

                        self.draw()

        def open(self, filename):
                self.clear()

                if self.subplotkludge:
                        self.subplot_new()

                self.subplotkludge = True

                with open(filename, 'r') as f:
                        storage = json.load(f)

                        print 'File: %s' % (filename)
                        print 'Timestamp: %s' % (storage['timestamp'])

                        for data in storage['data']:
                                self.plotl(data['x'], data['y'],
xlabel=data['xlabel'], ylabel=data['ylabel'],
                                           style=data['style'],
color=int(data['color'], 0))

                self.draw()

                if not self.props.overlay:
                        self.__storage['data'] =

                self.__storage['data'].extend(storage['data'])

        def save(self, filename):
                self.__storage['timestamp'] = time.ctime(time.time())

                with open(filename, 'w') as f:
                        json.dump(self.__storage, f, indent=8)

        # TODO:
        def stats(self, x, y):
                print ' len =', len(y)
                print ' mean =', numpy.mean(y)
                print ' sum =', sum(y)
                print ' std =', numpy.std(y)

                ymin = numpy.min(y)
                print ' ymin =', ymin
                print ' xmin =', x[y.index(ymin)]

                ymax = numpy.max(y)
                print ' ymax =', ymax
                print ' xmax =', x[y.index(ymax)]

        def __plot__(self, x, y, style=None, color=0xFF0000,
xlabel=None, ylabel=None):
                self.stats(x, y)

                data = {
                        'xlabel': xlabel,
                        'x': x,
                        'ylabel': ylabel,
                        'y': y,
                        'style': style,
                        'color': '0x%06X' % (color)
                }

                if not self.props.overlay:
                        self.__storage['data'] =

                self.__storage['data'].append(data)

        def plotr(self, *args, **kwargs):
                self.__plot__(*args, **kwargs)

        def plotl(self, *args, **kwargs):
                self.__plot__(*args, **kwargs)

        def ploth(self, *args, **kwargs):
                self.__plot__(*args, **kwargs)

        def plotv(self, *args, **kwargs):
                self.__plot__(*args, **kwargs)

        def draw(self, *args, **kwargs):
                pass

        def clear(self, *args, **kwargs):
                pass

        def show(self, *args, **kwargs):
                pass

        def hide(self, *args, **kwargs):
                pass

        def run(self, *args, **kwargs):
                pass

        def __init__(self):
                Object.__init__(self)

                self.__storage = {
                        'data':
                }

class ConsoleBackend(IBackend):
        """This is the simplest of backends. This simply prints to the
console. This backend
        must be used within a ConsoleContainer.
        """

        def __plot__(self, x, y, style=None, color=0xFF0000,
xlabel=None, ylabel=None):
                IBackend.__plot__(self, x, y, style=style,
color=color, xlabel=xlabel, ylabel=ylabel)

                for i in range(0, len(x)):
                        print 'x,y[%d] = %.4f, %4f' % (i, x[i], y[i])

class IMatplotlibBackend(IBackend):
        """This backend uses matplotlib to prodce plots. An
ImageContainer or WindowContainer in-turn
        contains this backed to either render the plot to and image or to a GUI.
        """

        def __plot__(self, x, y, style='-', color=0xFF0000,
xlabel=None, ylabel=None):
                IBackend.__plot__(self, x, y, style=style,
color=color, xlabel=xlabel, ylabel=ylabel)

                if xlabel != None:
                        self.__subplot.set_xlabel(xlabel)
                if ylabel != None:
                        self.__subplot.set_ylabel(ylabel)

                self.__subplot.plot(x, y, style, color='#%06X' % (color))
                self.__subplot.grid(True)

        def plotr(self, *args, **kwargs):
                self.figure.sca(self.__axr)
                if not kwargs.has_key('color'):
                        kwargs['color'] = 0x00FF00
                self.__plot__(*args, **kwargs)

        def plotl(self, *args, **kwargs):
                self.figure.sca(self.__axl)
                if not kwargs.has_key('color'):
                        kwargs['color'] = 0xFF0000
                self.__plot__(*args, **kwargs)

        def ploth(self, y, style='--', color=0xFF0000):
                self.__subplot.axhline(y, ls=style, color='#%06X' % (color))
                self.__subplot.grid(True)

        def plotv(self, x, style='--', color=0xFF0000):
                self.__subplot.axvline(x, ls=style, color='#%06X' % (color))
                self.__subplot.grid(True)

        def draw(self):
                self.__subplot.axis('auto')

                limits = [self.props.xmin, self.props.xmax,
self.props.ymin, self.props.ymax]

                if filter(lambda x: x != 0, limits):
                        self.__subplot.axis(limits)

                self.canvas.draw()

        def clear(self):
                if self.props.overlay:
                        return

                self.__subplot.clear()
                self.__subplot.grid(True)

        def subplot_new(self):
                nsubplots = len(self.__subplots) + 1

                subplot = self.figure.add_subplot(nsubplots, 1, nsubplots)
                subplot.grid(True)

                self.__subplots.append(subplot)
                self.__subplot = subplot

                for i, subplot in enumerate(self.__subplots):
                        subplot.change_geometry(nsubplots, 1, i + 1)

        def __init__(self):
                IBackend.__init__(self)

                from matplotlib.figure import Figure
                self.figure = Figure()

                self.__subplots =
                self.subplot_new()

                self.subplotkludge = False

                self.__axl = self.figure.gca()
                self.__axl.yaxis.set_label_position('left')
                self.__axl.yaxis.tick_left()

                self.__axr = self.__axl.twinx()
                self.__axr.yaxis.set_label_position('right')
                self.__axr.yaxis.tick_right()

class MatplotlibImageBackend(IMatplotlibBackend):

        def render(self, filename):
                self.figure.savefig(filename)

        def __init__(self):
                IMatplotlibBackend.__init__(self)

                from matplotlib.backends.backend_cairo \
                  import FigureCanvasCairo as FigureCanvas

                self.canvas = FigureCanvas(self.figure)

class MatplotlibWindowBackend(IMatplotlibBackend):

        @Property
        def widget():
                def fget(self):
                        self.__widget = gtk.VBox()

                        self.__widget.pack_start(self.canvas)
                        self.__widget.pack_start(self.toolbar, False, False)

                        return self.__widget

                def fset(self, widget):
                        self.__widget = widget

                return locals()

        def show(self):
                self.__widget.show()
                self.canvas.show()
                self.toolbar.show()

        def hide(self):
                self.toolbar.hide()
                self.canvas.hide()
                self.__widget.hide()

        def __init__(self):
                IMatplotlibBackend.__init__(self)

                from matplotlib.backends.backend_gtk \
                  import FigureCanvasGTK as FigureCanvas

                self.canvas = FigureCanvas(self.figure)

                from matplotlib.backends.backend_gtk \
                  import NavigationToolbar2GTK as NavigationToolbar

                self.toolbar = NavigationToolbar(self.canvas, None)

##
## Containers...
##

class IContainer(Object):
        """The IContainer class is the base implementation for any
class that contains IBackends.
        e.g. console wrappers, image only wrappers, or fancy GUI
toolkits like GTK+.
        """

        @Property
        def props():
                def fget(self):
                        return self.backend.props

                def fset(self, props):
                        self.backend.props = props

                return locals()

        def plotr(self, *args, **kwargs):
                self.backend.plotr(*args, **kwargs)

        def plotl(self, *args, **kwargs):
                self.backend.plotl(*args, **kwargs)

        def ploth(self, *args, **kwargs):
                self.backend.ploth(*args, **kwargs)

        def plotv(self, *args, **kwargs):
                self.backend.plotv(*args, **kwargs)

        def draw(self, *args, **kwargs):
                self.backend.draw(*args, **kwargs)

        def clear(self, *args, **kwargs):
                self.backend.clear(*args, **kwargs)

        def show(self, *args, **kwargs):
                self.backend.show(*args, **kwargs)

        def hide(self, *args, **kwargs):
                self.backend.hide(*args, **kwargs)

        def run(self, *args, **kwargs):
                self.backend.run(*args, **kwargs)

        def stripchart(self, filename):
                self.backend.stripchart(filename)

        def open(self, filename):
                self.backend.open(filename)

        def save(self, filename):
                self.backend.save(filename)

class ConsoleContainer(IContainer):

        def __init__(self):
                IContainer.__init__(self)

                self.backend = ConsoleBackend()

class ImageContainer(IContainer):

        def draw(self, *args, **kwargs):
                IContainer.draw(self, *args, **kwargs)

                self.backend.render('foobar.png')

        def __init__(self):
                IContainer.__init__(self)

                self.backend = MatplotlibImageBackend()

class WindowContainer(IContainer):

        @Property
        def props():
                def fget(self):
                        return self.backend.props

                def fset(self, props):
                        self.backend.props = props

                        widget =
self.__builder.get_object('preferences_xmin_entry')
                        widget.set_text(str(self.backend.props.xmin))

                        widget =
self.__builder.get_object('preferences_xmax_entry')
                        widget.set_text(str(self.backend.props.xmax))

                        widget =
self.__builder.get_object('preferences_ymin_entry')
                        widget.set_text(str(self.backend.props.ymin))

                        widget =
self.__builder.get_object('preferences_ymax_entry')
                        widget.set_text(str(self.backend.props.ymax))

                return locals()

        @Property
        def title():
                def fget(self):
                        return self.__title

                def fset(self, title):
                        self.__title = title

                        if not self.__title:
                                return

                        self.__container.set_title(self.__title)

                return locals()

        def clear(self, *args, **kwargs):
                IContainer.clear(self, *args, **kwargs)

        def show(self, *args, **kwargs):
                IContainer.show(self, *args, **kwargs)

                self.__container.show()

        def hide(self, *args, **kwargs):
                IContainer.hide(self, *args, **kwargs)

                self.__container.hide()

        def run(self):
                gtk.main()

        def on_open_ok_button_clicked(self, widget, data=None):
                self.__open.hide()

                filename = self.__open.get_filename()
                if not filename:
                        return
                self.__open.set_filename(filename)

                self.open(filename)

        def on_open_cancel_button_clicked(self, widget, data=None):
                self.__open.hide()

        def on_open_chooser_delete_event(self, widget, data=None):
                self.__open.hide()
                return True

        def on_plot_open_button_clicked(self, widget, data=None):
                self.__open = self.__builder.get_object('open_chooser')
                self.__open.show()

        def on_plot_save_button_clicked(self, widget, data=None):
                if not self.filename:
                        self.on_plot_saveas_button_clicked(self, None)

                if self.filename:
                        self.save(self.filename)

        def on_saveas_ok_button_clicked(self, widget, data=None):
                self.__saveas.hide()

                filename = self.__saveas.get_filename()
                if not filename:
                        return
                self.__saveas.set_filename(filename)

                self.filename = filename

                self.on_plot_save_button_clicked(self, None)

        def on_saveas_cancel_button_clicked(self, widget, data=None):
                self.__saveas.hide()

        def on_saveas_chooser_delete_event(self, widget, data=None):
                self.__saveas.hide()
                return True

        def on_plot_saveas_button_clicked(self, widget, data=None):
                self.__saveas = self.__builder.get_object('saveas_chooser')
                self.__saveas.show()

        def on_preferences_ok_button_clicked(self, widget, data=None):
                self.__preferences.hide()

                widget = self.__builder.get_object('preferences_xmin_entry')
                self.props.xmin = float(widget.get_text())

                widget = self.__builder.get_object('preferences_xmax_entry')
                self.props.xmax = float(widget.get_text())

                widget = self.__builder.get_object('preferences_ymin_entry')
                self.props.ymin = float(widget.get_text())

                widget = self.__builder.get_object('preferences_ymax_entry')
                self.props.ymax = float(widget.get_text())

                self.draw()

        def on_preferences_cancel_button_clicked(self, widget, data=None):
                self.__preferences.hide()

        def on_plot_preferences_button_clicked(self, widget, data=None):
                self.__preferences =
self.__builder.get_object('preferences_dialog')
                self.__preferences.show()

        def on_preferences_dialog_delete_event(self, widget, data=None):
                self.__preferences.hide()
                return True

        def on_plot_overlay_button_toggled(self, widget, data=None):
                self.props.overlay = widget.get_active()

        def on_plot_window_destroy(self, widget, data=None):
                gtk.main_quit()

        def __init__(self, container):
                IContainer.__init__(self)

                self.backend = MatplotlibWindowBackend()

                buildername = os.environ['GRIMA_ETC'] + os.sep + 'grima-plot.ui'
                self.__builder = gtk.Builder()
                self.__builder.add_from_file(buildername)
                self.__builder.connect_signals(self)

                if container:
                        self.__container = container
                        widget = self.__builder.get_object('plot_embeddable')
                        container = self.__builder.get_object('plot_container')
                        container.remove(widget)
                        self.__container.add(widget)
                else:
                        self.__container =
self.__builder.get_object('plot_window')

                        # TODO: this should not be needed, but somehow
the widget show'ing order
                        # is all screwed up and the window doesn't
display correctly without this
                        self.__container.set_default_size(700, 500)

                widget = self.__builder.get_object('plot_backend')
                widget.add(self.backend.widget)

                # TODO:
                self.filename = None

##
## This is the public API...
##

class Plot(Object):

        def __create_display(self):
                if not self.__enabled:
                        return

                if self.type == 'console':
                        self.__display = ConsoleContainer()
                if self.type == 'image':
                        self.__display = ImageContainer()
                if self.type == 'window':
                        self.__display = WindowContainer(self.container)

                try:
                        self.__display.props = self
                        self.__display.title = self.title
                except:
                        self.__enabled = False

        @Property
        def enabled():
                def fget(self):
                        return self.__enabled

                def fset(self, enabled):
                        self.__enabled = enabled
                        self.__create_display()

                return locals()

        @Property
        def type():
                def fget(self):
                        return self.__type

                def fset(self, type):
                        self.__type = type
                        self.__create_display()

                return locals()

        @Property
        def title():
                def fget(self):
                        return self.__title

                def fset(self, title):
                        self.__title = title

                return locals()

        def plotr(self, *args, **kwargs):
                if not self.enabled:
                        return

                self.__display.plotr(*args, **kwargs)

        def plotl(self, *args, **kwargs):
                if not self.enabled:
                        return

                self.__display.plotl(*args, **kwargs)

        def ploth(self, *args, **kwargs):
                if not self.enabled:
                        return

                self.__display.ploth(*args, **kwargs)

        def plotv(self, *args, **kwargs):
                if not self.enabled:
                        return

                self.__display.plotv(*args, **kwargs)

        def draw(self, *args, **kwargs):
                if not self.enabled:
                        return

                self.__display.draw(*args, **kwargs)

        def clear(self, *args, **kwargs):
                if not self.enabled:
                        return

                self.__display.clear(*args, **kwargs)

        def show(self, *args, **kwargs):
                if not self.enabled:
                        return

                self.__display.show(*args, **kwargs)

        def hide(self, *args, **kwargs):
                if not self.enabled:
                        return

                self.__display.hide(*args, **kwargs)

        def run(self, *args, **kwargs):
                if not self.enabled:
                        return

                self.__display.run(*args, **kwargs)

        def stripchart(self, *args, **kwargs):
                if not self.enabled:
                        return

                self.__display.stripchart(*args, **kwargs)

        def open(self, *args, **kwargs):
                if not self.enabled:
                        return

                self.__display.open(*args, **kwargs)

        def save(self, *args, **kwargs):
                if not self.enabled:
                        return

                self.__display.save(*args, **kwargs)

        def __init__(self):
                Object.__init__(self)

                self.enabled = False
                self.container = None
                self.type = 'console'
                self.title = None

                # TODO: use preferences
                self.xmin = 0
                self.xmax = 0
                self.ymin = 0
                self.ymax = 0
                self.overlay = False

# Local Variables:
# indent-tabs-mode: nil
# python-continuation-offset: 2
# python-indent: 8
# End:
# vim: ai et si sw=8 ts=8

Tom Vaughan wrote:

post some code

I thought this might be required...

So the whole thing is excessively complex.

It can be very instructive to write a little app that just tests the issue at hand -- it may help you figure out what's wrong, and if not, you will have a self-contained sample that you can post here for feedback.

I think the relevant parts are:

                from matplotlib.figure import Figure

                self.__axl = self.figure.gca()

I don't know what your issue is, but I thin you will be ell served to use the OO interface, rather than pylab to write a complex app like this -- pylab is designed for simple interactive use and quick scripts. In an app, you want full control.

-Chris

···

--
Christopher Barker, Ph.D.
Oceanographer

Emergency Response Division
NOAA/NOS/OR&R (206) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception

Chris.Barker@...259...

This is the API -- figure is a Figure instance, and gca is a figure
method. pyplot.gca is a wrapper around this method. The Figure
tracks the "current" axes, but the API doesn't really use this method
other than to provide it for pyplot.

But the larger point is still well taken -- you should probably be
using self.figure.add_subplot(111) here rather than gca.

JDH

···

On Tue, Jun 2, 2009 at 4:34 PM, Christopher Barker <Chris.Barker@...259...> wrote:

I think the relevant parts are:

                from matplotlib.figure import Figure

                self.__axl = self.figure.gca()

I don't know what your issue is, but I thin you will be ell served to
use the OO interface, rather than pylab to write a complex app like this
-- pylab is designed for simple interactive use and quick scripts. In an
app, you want full control.

twinx() does not return an axes that contains the change_geometry
method. How then can I do the equivalent on this axes? Calling twinx()
again on the original axes after change_geometry() has been called
does not do the trick. Thanks.

-Tom

···

On Tue, Jun 2, 2009 at 07:33, John Hunter<jdh2358@...287...> wrote:

On Tue, Jun 2, 2009 at 9:03 AM, Tom Vaughan <tom@...2628...> wrote:

Is it possible to add subplots to a figure if I don't know in advance
how many subplots I need to add?

What I do now is I call add_subplot like add_subplot(i, 1, i) where i
is 1 initially, and just increases by 1 on each call. This almost
works. Except the first plot takes up the whole figure, the second
plot is placed on top of the bottom half of the first plot, etc. Is
there a way to "resize" the plots when a subplot is added? Or how
would I "re-plot" the previous subplots?

See the Axes.change_geometry command

http://matplotlib.sourceforge.net/api/axes_api.html#matplotlib.axes.SubplotBase.change_geometry

One work around is to call

  self.figure.subplots_adjust()

after geometry changed. After this call, the twinx-ed axes will have
the same axes position as the original one.

Another option is to use mpl_toolkits.axes_grid
(http://matplotlib.sourceforge.net/mpl_toolkits/axes_grid/users/overview.html#parasiteaxes).
But the previous solution seems to be much easier for you.
Regards,

-JJ

···

On Thu, Jul 16, 2009 at 1:16 PM, Tom Vaughan<tom@...2628...> wrote:

On Tue, Jun 2, 2009 at 07:33, John Hunter<jdh2358@...287...> wrote:

On Tue, Jun 2, 2009 at 9:03 AM, Tom Vaughan <tom@...2628...> wrote:

Is it possible to add subplots to a figure if I don't know in advance
how many subplots I need to add?

What I do now is I call add_subplot like add_subplot(i, 1, i) where i
is 1 initially, and just increases by 1 on each call. This almost
works. Except the first plot takes up the whole figure, the second
plot is placed on top of the bottom half of the first plot, etc. Is
there a way to "resize" the plots when a subplot is added? Or how
would I "re-plot" the previous subplots?

See the Axes.change_geometry command

http://matplotlib.sourceforge.net/api/axes_api.html#matplotlib.axes.SubplotBase.change_geometry

twinx() does not return an axes that contains the change_geometry
method. How then can I do the equivalent on this axes? Calling twinx()
again on the original axes after change_geometry() has been called
does not do the trick. Thanks.

-Tom

------------------------------------------------------------------------------
Enter the BlackBerry Developer Challenge
This is your chance to win up to $100,000 in prizes! For a limited time,
vendors submitting new applications to BlackBerry App World(TM) will have
the opportunity to enter the BlackBerry Developer Challenge. See full prize
details at: http://p.sf.net/sfu/Challenge
_______________________________________________
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
matplotlib-users List Signup and Options

Great. That worked. Thanks!

-Tom

···

On Thu, Jul 16, 2009 at 11:23, Jae-Joon Lee<lee.j.joon@...287...> wrote:

One work around is to call

self.figure.subplots_adjust()

after geometry changed. After this call, the twinx-ed axes will have
the same axes position as the original one.

Another option is to use mpl_toolkits.axes_grid
(http://matplotlib.sourceforge.net/mpl_toolkits/axes_grid/users/overview.html#parasiteaxes).
But the previous solution seems to be much easier for you.
Regards,

-JJ

On Thu, Jul 16, 2009 at 1:16 PM, Tom Vaughan<tom@...2628...> wrote:

On Tue, Jun 2, 2009 at 07:33, John Hunter<jdh2358@...287...> wrote:

On Tue, Jun 2, 2009 at 9:03 AM, Tom Vaughan <tom@...2628...> wrote:

Is it possible to add subplots to a figure if I don't know in advance
how many subplots I need to add?

What I do now is I call add_subplot like add_subplot(i, 1, i) where i
is 1 initially, and just increases by 1 on each call. This almost
works. Except the first plot takes up the whole figure, the second
plot is placed on top of the bottom half of the first plot, etc. Is
there a way to "resize" the plots when a subplot is added? Or how
would I "re-plot" the previous subplots?

See the Axes.change_geometry command

http://matplotlib.sourceforge.net/api/axes_api.html#matplotlib.axes.SubplotBase.change_geometry

twinx() does not return an axes that contains the change_geometry
method. How then can I do the equivalent on this axes? Calling twinx()
again on the original axes after change_geometry() has been called
does not do the trick. Thanks.

-Tom

------------------------------------------------------------------------------
Enter the BlackBerry Developer Challenge
This is your chance to win up to $100,000 in prizes! For a limited time,
vendors submitting new applications to BlackBerry App World(TM) will have
the opportunity to enter the BlackBerry Developer Challenge. See full prize
details at: http://p.sf.net/sfu/Challenge
_______________________________________________
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
matplotlib-users List Signup and Options

--
Website: www.software6.net
E-mail/Google Talk: tom (at) software6 (dot) net
Mobile: +1 (310) 751-0187