more on plugins/toolbar

Okay, I think I've gotten all the major bugs out, and the code can be upgraded from 'major hack' to 'minor hack'. The files that were changed (as well as a directory patch) can be found at:

http://www.cns.nyu.edu/~abes/matplotlib/

This code currently only works/tested with GTK and with the pygtk2.2 section (although the 2.4 section is trivial to update). All the major changes were to the backend_bases.py file, so it should also be trivial to port it to the other backends as well (i.e. basically just a copy and paste).

All toolbar functionality is now handled in the plugin file 'toolbar.py' file using various children of 'toolbar_widget'. I had to change the syntax in the .matplotlibrc file somewhat to allow variable arguments to the widgets (e.g. the 'view_controller' doesn't need tooltips, or text, as it isn't visible) to:

toolbar.widget: <toolbar, home_button>: home, Home, Reset original view

where in, '<toolbar, home_button>:', toolbar is the module name, and home_button is the class. The rest are arguments (name, text, and tooltip in this case). There is a small issue with the fact that commas cannot be included in the tooltips.

I also fixed the plugins.py code so that it will now search multiple plugin paths, deliminated by ':'.

The files 'toolbar.py' and 'print.py' have to go into the plugins directory for this to work, and the other python files into their normal locations.

Except for changing the cursors (I didn't get around to writing that code), it appears to work exactly the same as the old version (helped tremendously of course by using mostly the same code).

Abe

Abraham Schneider wrote:

Okay, I think I've gotten all the major bugs out, and the code can be upgraded from 'major hack' to 'minor hack'. The files that were changed (as well as a directory patch) can be found at:

http://www.cns.nyu.edu/~abes/matplotlib/

[...]

I've stayed off this discussion because I'm a bit swamped, but I'd like to make a couple of quick comments.

1. I think plugin support is a fantastic idea, but I hope it can be made user-extensible in local paths. I recently modified mayavi (available in current CVS) precisely in this manner, and I think it's a very useful thing. In lab settings where users are not allowed to write to system directories, it becomes very important that they can add their own plugins in local paths. This also allows you to keep your personal extensions alive as matplotlib versions are upgraded, since your directories are untouched.

What I did for mayavi was to add a search-path option to mayavi, made of colon-separated dirs with ~user/$VAR support. Any such dir gets added to mayavi's search path for user-defined filters and modules (the equivalent of plugins), and you can load a user module just like you can load a builtin:

load_module('Glyphs') -> loads mayavi's Glyphs module
load_module('User.Glyphs') -> loads a user-defined Glyphs module from the search path.

I think it's important that it's a _path_ and not a single directory, because this allows a research group to maintain shared extensions suited for their purposes, and individual users to add personal modifications which don't fit group projects.

2. From some of your syntax struggles, I'm starting to wonder whether it would be best to turn the .matplotlibrc file into a proper python one. I followed the same approach with ipython of having a custom syntax, and now I regret it. It appears easier initially, but in the long term it's clunky (at least for ipython). For ipython's next major revision, I plan on dumping its own rc format and allowing users to define their configuration using plain python syntax. Just some thoughts.

Anyway, I htink this is great for matplotlib, and I hope you can bring it to a good conclusion. Great work!

Best,

f

Fernando Perez wrote:

1. I think plugin support is a fantastic idea, but I hope it can be made user-extensible in local paths. I recently modified mayavi (available in current CVS) precisely in this manner, and I think it's a very useful thing. In lab settings where users are not allowed to write to system directories, it becomes very important that they can add their own plugins in local paths. This also allows you to keep your personal extensions alive as matplotlib versions are upgraded, since your directories are untouched.

What I did for mayavi was to add a search-path option to mayavi, made of colon-separated dirs with ~user/$VAR support. Any such dir gets added to mayavi's search path for user-defined filters and modules (the equivalent of plugins), and you can load a user module just like you can load a builtin:

load_module('Glyphs') -> loads mayavi's Glyphs module
load_module('User.Glyphs') -> loads a user-defined Glyphs module from the search path.

I think it's important that it's a _path_ and not a single directory, because this allows a research group to maintain shared extensions suited for their purposes, and individual users to add personal modifications which don't fit group projects.

I completely agree. I recently changed the code to allow a path to be specified (':' deliminated). I hadn't thought of allowing '$VAR' syntax .. something to think about. However, if people have a .matplotlibrc file in their home directory, it should make it so people aren't mucking up things with the plugins.. I'll have to check the behavior of find_module to see what it does with '~' and such.

I like the idea of 'load_module'. Currently all the plugins in the directories are loaded automatically. There is a certain nicety, though, to automatically having it load all the plugins found in a particular directory. Less cumbersome for most users.

Abe

Abraham Schneider wrote:

I completely agree. I recently changed the code to allow a path to be specified (':' deliminated). I hadn't thought of allowing '$VAR' syntax .. something to think about. However, if people have a .matplotlibrc file in their home directory, it should make it so people aren't mucking up things with the plugins.. I'll have to check the behavior of find_module to see what it does with '~' and such.

You can expand the user-given string by doing:

user_dirlist = os.path.expanduser(os.path.expandvars(user_path)).split(':')

This gives you a list of directories to search, with user ~names and $VARIABLES expanded out. This approach worked fine for mayavi.

Best,

f