Graphic properties editing

Hi,

I have written a small pygtk script to allow dynamic editing of the
current graphs. It is useful in interactive use of matplotlib. It can
handle figures, axes, text, images, lines properties. You can copy lines
from one axes to an other one or delete elements. Finally you can save
the data in ASCII. Before doing more developments, I'd like to know if
such a tool already exists. Otherwise, your comments are welcome.

You can find the script here (Quick & Dirty coding style) :
http://mpl-properties.googlecode.com/svn/trunk/mpl_properties.py

to test it, in an interactive pylab session with figures and plots, just
type these 2 commands:

import mpl_properties
mpl_properties.properties()

Antoine

Very nice and useful script Antoine !

I have never heard about such a script before.

Pyplotsuite is another pygtk project using matplotlib.
It is developed by Antonino Ingargiola.
http://pyplotsuite.sourceforge.net/
Could be maybe interesting to join the effort on providing nice pygtk
tools for matplotlib sharing common elements of this two projects.
Just a suggestion...

I'm very pleased to see there is an active and growing community using
matplotlib together with pygtk.

Regards,

David

2007/6/19, Antoine Sirinelli <matplotlib-users@...1652...>:

···

Hi,

I have written a small pygtk script to allow dynamic editing of the
current graphs. It is useful in interactive use of matplotlib. It can
handle figures, axes, text, images, lines properties. You can copy lines
from one axes to an other one or delete elements. Finally you can save
the data in ASCII. Before doing more developments, I'd like to know if
such a tool already exists. Otherwise, your comments are welcome.

You can find the script here (Quick & Dirty coding style) :
http://mpl-properties.googlecode.com/svn/trunk/mpl_properties.py

to test it, in an interactive pylab session with figures and plots, just
type these 2 commands:

import mpl_properties
mpl_properties.properties()

Antoine

-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-users

Hi,

I have written a small pygtk script to allow dynamic editing of the
current graphs. It is useful in interactive use of matplotlib. It can
handle figures, axes, text, images, lines properties. You can copy lines
from one axes to an other one or delete elements. Finally you can save
the data in ASCII. Before doing more developments, I'd like to know if
such a tool already exists. Otherwise, your comments are welcome.

Hi Antonione --

this is a nice start. A couple of suggestions

* you may want to use a gtk.Table for your label/entry pairs in your
dialog editor. Everything will line up much more nicely

* you should not explicitly require pygtk 2.0. Noone is using pygtk1
anymore and this will cause some pygth2 installations to fail (like
mine!)

* you may want to look at the line editor dialog in backend_gtk.py for
inspiration. This uses drop down menus for linestyles, color dialog
boxes to pick colors, etc... I'll paste in the code below

Thanks,
JDH

class DialogLineprops:
    """
    A GUI dialog for controlling lineprops
    """
    signals = (
        'on_combobox_lineprops_changed',
        'on_combobox_linestyle_changed',
        'on_combobox_marker_changed',
        'on_colorbutton_linestyle_color_set',
        'on_colorbutton_markerface_color_set',
        'on_dialog_lineprops_okbutton_clicked',
        'on_dialog_lineprops_cancelbutton_clicked',
        )

    linestyles = (
        '-' ,
        '--' ,
        '-.' ,
        ',' ,
        'steps',
        'None' ,
    )

    linestyled = dict([ (s,i) for i,s in enumerate(linestyles)])

    markers = (
        'None',
        '.' ,
        ',' ,
        'o' ,
        'v' ,
        '^' ,
        '<' ,
        '>' ,
        '1' ,
        '2' ,
        '3' ,
        '4' ,
        's' ,
        'p' ,
        'h' ,
        'H' ,
        '+' ,
        'x' ,
        'D' ,
        'd' ,
        '|' ,
        '_' ,
        )

    markerd = dict([(s,i) for i,s in enumerate(markers)])

    def __init__(self, lines):

        datadir = matplotlib.get_data_path()
        gladefile = os.path.join(datadir, 'lineprops.glade')
        if not os.path.exists(gladefile):
            raise IOError('Could not find gladefile lineprops.glade in
%s'%datadir)

        self._inited = False
        self._updateson = True # suppress updates when setting widgets manually
        self.wtree = gtk.glade.XML(gladefile, 'dialog_lineprops')
        self.wtree.signal_autoconnect(dict([(s, getattr(self, s)) for
s in self.signals]))

        self.dlg = self.wtree.get_widget('dialog_lineprops')

        self.lines = lines

        cbox = self.wtree.get_widget('combobox_lineprops')
        cbox.set_active(0)
        self.cbox_lineprops = cbox

        cbox = self.wtree.get_widget('combobox_linestyles')
        for ls in self.linestyles:
            cbox.append_text(ls)
        cbox.set_active(0)
        self.cbox_linestyles = cbox

        cbox = self.wtree.get_widget('combobox_markers')
        for m in self.markers:
            cbox.append_text(m)
        cbox.set_active(0)
        self.cbox_markers = cbox
        self._lastcnt = 0
        self._inited = True

    def show(self):
        'populate the combo box'
        self._updateson = False
        # flush the old
        cbox = self.cbox_lineprops
        for i in range(self._lastcnt-1,-1,-1):
            cbox.remove_text(i)

        # add the new
        for line in self.lines:
            cbox.append_text(line.get_label())
        cbox.set_active(0)

        self._updateson = True
        self._lastcnt = len(self.lines)
        self.dlg.show()

    def get_active_line(self):
        'get the active line'
        ind = self.cbox_lineprops.get_active()
        line = self.lines[ind]
        return line

    def get_active_linestyle(self):
        'get the active lineinestyle'
        ind = self.cbox_linestyles.get_active()
        ls = self.linestyles[ind]
        return ls

    def get_active_marker(self):
        'get the active lineinestyle'
        ind = self.cbox_markers.get_active()
        m = self.markers[ind]
        return m

    def _update(self):
        'update the active line props from the widgets'
        if not self._inited or not self._updateson: return
        line = self.get_active_line()
        ls = self.get_active_linestyle()
        marker = self.get_active_marker()
        line.set_linestyle(ls)
        line.set_marker(marker)

        button = self.wtree.get_widget('colorbutton_linestyle')
        color = button.get_color()
        r, g, b = [val/65535. for val in color.red, color.green, color.blue]
        line.set_color((r,g,b))

        button = self.wtree.get_widget('colorbutton_markerface')
        color = button.get_color()
        r, g, b = [val/65535. for val in color.red, color.green, color.blue]
        line.set_markerfacecolor((r,g,b))

        line.figure.canvas.draw()

    def on_combobox_lineprops_changed(self, item):
        'update the widgets from the active line'
        if not self._inited: return
        self._updateson = False
        line = self.get_active_line()

        ls = line.get_linestyle()
        if ls is None: ls = 'None'
        self.cbox_linestyles.set_active(self.linestyled[ls])

        marker = line.get_marker()
        if marker is None: marker = 'None'
        self.cbox_markers.set_active(self.markerd[marker])

        r,g,b = colorConverter.to_rgb(line.get_color())
        color = gtk.gdk.Color(*[int(val*65535) for val in r,g,b])
        button = self.wtree.get_widget('colorbutton_linestyle')
        button.set_color(color)

        r,g,b = colorConverter.to_rgb(line.get_markerfacecolor())
        color = gtk.gdk.Color(*[int(val*65535) for val in r,g,b])
        button = self.wtree.get_widget('colorbutton_markerface')
        button.set_color(color)
        self._updateson = True

    def on_combobox_linestyle_changed(self, item):
        self._update()

    def on_combobox_marker_changed(self, item):
        self._update()

    def on_colorbutton_linestyle_color_set(self, button):
        self._update()

    def on_colorbutton_markerface_color_set(self, button):
        'called colorbutton marker clicked'
        self._update()

    def on_dialog_lineprops_okbutton_clicked(self, button):
        self._update()
        self.dlg.hide()

    def on_dialog_lineprops_cancelbutton_clicked(self, button):
        self.dlg.hide()

···

On 6/19/07, Antoine Sirinelli <matplotlib-users@...1652...> wrote:

You can find the script here (Quick & Dirty coding style) :
http://mpl-properties.googlecode.com/svn/trunk/mpl_properties.py

to test it, in an interactive pylab session with figures and plots, just
type these 2 commands:

import mpl_properties
mpl_properties.properties()

Antoine

-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-users

Where can I find the lineprops.glade file ?

Thanks in advance,

David

2007/6/19, John Hunter <jdh2358@...287...>:

···

On 6/19/07, Antoine Sirinelli <matplotlib-users@...1652...> wrote:
> Hi,
>
> I have written a small pygtk script to allow dynamic editing of the
> current graphs. It is useful in interactive use of matplotlib. It can
> handle figures, axes, text, images, lines properties. You can copy lines
> from one axes to an other one or delete elements. Finally you can save
> the data in ASCII. Before doing more developments, I'd like to know if
> such a tool already exists. Otherwise, your comments are welcome.
>

Hi Antonione --

this is a nice start. A couple of suggestions

* you may want to use a gtk.Table for your label/entry pairs in your
dialog editor. Everything will line up much more nicely

* you should not explicitly require pygtk 2.0. Noone is using pygtk1
anymore and this will cause some pygth2 installations to fail (like
mine!)

* you may want to look at the line editor dialog in backend_gtk.py for
inspiration. This uses drop down menus for linestyles, color dialog
boxes to pick colors, etc... I'll paste in the code below

Thanks,
JDH

class DialogLineprops:
    """
    A GUI dialog for controlling lineprops
    """
    signals = (
        'on_combobox_lineprops_changed',
        'on_combobox_linestyle_changed',
        'on_combobox_marker_changed',
        'on_colorbutton_linestyle_color_set',
        'on_colorbutton_markerface_color_set',
        'on_dialog_lineprops_okbutton_clicked',
        'on_dialog_lineprops_cancelbutton_clicked',
        )

    linestyles = (
        '-' ,
        '--' ,
        '-.' ,
        ',' ,
        'steps',
        'None' ,
    )

    linestyled = dict([ (s,i) for i,s in enumerate(linestyles)])

    markers = (
        'None',
        '.' ,
        ',' ,
        'o' ,
        'v' ,
        '^' ,
        '<' ,
        '>' ,
        '1' ,
        '2' ,
        '3' ,
        '4' ,
        's' ,
        'p' ,
        'h' ,
        'H' ,
        '+' ,
        'x' ,
        'D' ,
        'd' ,
        '|' ,
        '_' ,
        )

    markerd = dict([(s,i) for i,s in enumerate(markers)])

    def __init__(self, lines):

        datadir = matplotlib.get_data_path()
        gladefile = os.path.join(datadir, 'lineprops.glade')
        if not os.path.exists(gladefile):
            raise IOError('Could not find gladefile lineprops.glade in
%s'%datadir)

        self._inited = False
        self._updateson = True # suppress updates when setting widgets manually
        self.wtree = gtk.glade.XML(gladefile, 'dialog_lineprops')
        self.wtree.signal_autoconnect(dict([(s, getattr(self, s)) for
s in self.signals]))

        self.dlg = self.wtree.get_widget('dialog_lineprops')

        self.lines = lines

        cbox = self.wtree.get_widget('combobox_lineprops')
        cbox.set_active(0)
        self.cbox_lineprops = cbox

        cbox = self.wtree.get_widget('combobox_linestyles')
        for ls in self.linestyles:
            cbox.append_text(ls)
        cbox.set_active(0)
        self.cbox_linestyles = cbox

        cbox = self.wtree.get_widget('combobox_markers')
        for m in self.markers:
            cbox.append_text(m)
        cbox.set_active(0)
        self.cbox_markers = cbox
        self._lastcnt = 0
        self._inited = True

    def show(self):
        'populate the combo box'
        self._updateson = False
        # flush the old
        cbox = self.cbox_lineprops
        for i in range(self._lastcnt-1,-1,-1):
            cbox.remove_text(i)

        # add the new
        for line in self.lines:
            cbox.append_text(line.get_label())
        cbox.set_active(0)

        self._updateson = True
        self._lastcnt = len(self.lines)
        self.dlg.show()

    def get_active_line(self):
        'get the active line'
        ind = self.cbox_lineprops.get_active()
        line = self.lines[ind]
        return line

    def get_active_linestyle(self):
        'get the active lineinestyle'
        ind = self.cbox_linestyles.get_active()
        ls = self.linestyles[ind]
        return ls

    def get_active_marker(self):
        'get the active lineinestyle'
        ind = self.cbox_markers.get_active()
        m = self.markers[ind]
        return m

    def _update(self):
        'update the active line props from the widgets'
        if not self._inited or not self._updateson: return
        line = self.get_active_line()
        ls = self.get_active_linestyle()
        marker = self.get_active_marker()
        line.set_linestyle(ls)
        line.set_marker(marker)

        button = self.wtree.get_widget('colorbutton_linestyle')
        color = button.get_color()
        r, g, b = [val/65535. for val in color.red, color.green, color.blue]
        line.set_color((r,g,b))

        button = self.wtree.get_widget('colorbutton_markerface')
        color = button.get_color()
        r, g, b = [val/65535. for val in color.red, color.green, color.blue]
        line.set_markerfacecolor((r,g,b))

        line.figure.canvas.draw()

    def on_combobox_lineprops_changed(self, item):
        'update the widgets from the active line'
        if not self._inited: return
        self._updateson = False
        line = self.get_active_line()

        ls = line.get_linestyle()
        if ls is None: ls = 'None'
        self.cbox_linestyles.set_active(self.linestyled[ls])

        marker = line.get_marker()
        if marker is None: marker = 'None'
        self.cbox_markers.set_active(self.markerd[marker])

        r,g,b = colorConverter.to_rgb(line.get_color())
        color = gtk.gdk.Color(*[int(val*65535) for val in r,g,b])
        button = self.wtree.get_widget('colorbutton_linestyle')
        button.set_color(color)

        r,g,b = colorConverter.to_rgb(line.get_markerfacecolor())
        color = gtk.gdk.Color(*[int(val*65535) for val in r,g,b])
        button = self.wtree.get_widget('colorbutton_markerface')
        button.set_color(color)
        self._updateson = True

    def on_combobox_linestyle_changed(self, item):
        self._update()

    def on_combobox_marker_changed(self, item):
        self._update()

    def on_colorbutton_linestyle_color_set(self, button):
        self._update()

    def on_colorbutton_markerface_color_set(self, button):
        'called colorbutton marker clicked'
        self._update()

    def on_dialog_lineprops_okbutton_clicked(self, button):
        self._update()
        self.dlg.hide()

    def on_dialog_lineprops_cancelbutton_clicked(self, button):
        self.dlg.hide()

> You can find the script here (Quick & Dirty coding style) :
> http://mpl-properties.googlecode.com/svn/trunk/mpl_properties.py
>
> to test it, in an interactive pylab session with figures and plots, just
> type these 2 commands:
>
> import mpl_properties
> mpl_properties.properties()
>
> Antoine
>
> -------------------------------------------------------------------------
> This SF.net email is sponsored by DB2 Express
> Download DB2 Express C - the FREE version of DB2 express and take
> control of your XML. No limits. Just data. Click to get it now.
> http://sourceforge.net/powerbar/db2/
> _______________________________________________
> Matplotlib-users mailing list
> Matplotlib-users@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/matplotlib-users
>

-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-users

It should be in mpl-data but it was removed from svn at some point. I
just tried readding it but svn is not letting me commit. I'll attach
it here

lineprops.glade (11.1 KB)

···

On 6/19/07, David Tremouilles <david.trem@...287...> wrote:

Where can I find the lineprops.glade file ?

* you may want to use a gtk.Table for your label/entry pairs in your
dialog editor. Everything will line up much more nicely

It was on my TODO list. Now it's done.

* you should not explicitly require pygtk 2.0. Noone is using pygtk1
anymore and this will cause some pygth2 installations to fail (like
mine!)

OK. I never understood indeed why in most of the pygtk exemple this line
was present. I have removed it.

* you may want to look at the line editor dialog in backend_gtk.py for
inspiration. This uses drop down menus for linestyles, color dialog
boxes to pick colors, etc... I'll paste in the code below

Ok, I'll have a look. I was thinking of this kind of menu.

Thanks,

Antoine

···

On Tue, Jun 19, 2007 at 08:46:17AM -0500, John Hunter wrote:

Pyplotsuite is another pygtk project using matplotlib.
It is developed by Antonino Ingargiola.
http://pyplotsuite.sourceforge.net/
Could be maybe interesting to join the effort on providing nice pygtk
tools for matplotlib sharing common elements of this two projects.
Just a suggestion...

Interesting project. Thanks for the link, I didn't know this project.

I'm very pleased to see there is an active and growing community using
matplotlib together with pygtk.

I am using pygtk and matplotlib in my work for building interfaces to
data analysis programs (numpy, scipy and C).

Antoine

···

On Tue, Jun 19, 2007 at 02:12:28PM +0200, David Tremouilles wrote:

Hi,

2007/6/19, Antoine Sirinelli <matplotlib-users@...1652...>:

> Pyplotsuite is another pygtk project using matplotlib.
> It is developed by Antonino Ingargiola.
> http://pyplotsuite.sourceforge.net/
> Could be maybe interesting to join the effort on providing nice pygtk
> tools for matplotlib sharing common elements of this two projects.
> Just a suggestion...

Interesting project. Thanks for the link, I didn't know this project.

Because has not been announced anywhere yet :D.

Antoine, I like the idea of your script. I really would like to see a
such thing included in matplotlib eventually. It would help either to quick
modify *all* the plot parameters and to have an immediate visual
representation of the matplotlib hierarchies. So would help both
matplotlib
script's users and (matplotlib) programmers as well.

As suggestion I think would be useful to divide the properties in three
groups: free text, number and list and use for each of then a text entry, a
spin button or a combo box. Don't be offended if this is obvious to you :).

I've implemented a somewhat similar dialog for Plotfile2 (one of the
two scripts composing PyPlotSuite). My dialog although "similar" is
more limited
in scope. If you are interested you can see the dialog class here (line
566):

http://repo.or.cz/w/pyplotsuite.git?a=blob;f=plotfile2.py;h=aa089c3e09957d36396e4f3b97fbfb38d58c44de;hb=HEAD

and a screenshot to see how it looks like:

http://pyplotsuite.sourceforge.net/images/plotfile2-screenshot2.png

I will use your implementation and John Hunter's DialogLineprops as
source of inspiration. Thanks...

> I'm very pleased to see there is an active and growing community using
> matplotlib together with pygtk.

I am using pygtk and matplotlib in my work for building interfaces to
data analysis programs (numpy, scipy and C).

I've do this for my own purpose. After a while I decided to publish
some of my scripts so PyPlotSuite was born. The purpose is to allow
the user to visualize/analyze data without knowing python or
matplotlib. Ideally my scripts would be associated to specific file
types so that the file manager opens the data with the correct
"visualizer" (at least this is how I use them).

I'm open in any kind of collaboration, in both senses. I'm just a bit
limited in time ATM.

Regards,

    ~ Antonio

···

On Tue, Jun 19, 2007 at 02:12:28PM +0200, David Tremouilles wrote:

Hi,

2007/6/19, John Hunter <jdh2358@...287...>:

<snip>

* you may want to look at the line editor dialog in backend_gtk.py for
inspiration. This uses drop down menus for linestyles, color dialog
boxes to pick colors, etc... I'll paste in the code below

Thanks,
JDH

class DialogLineprops:

Just for the record, I had to explicitly import gtk.glade and to put a
self.show() call in the __init__() method to make this work.

Nice example though. Thanks :).

Regards,

    ~ Antonio