Script that wraps (haunts) objects and tracks all changes to them, the matplotlib part is not useful (espeacially since pickling support is there or almost there), but its a funny hack so I keep it around.
Fetching latest commit…
Cannot retrieve the latest commit at this time
Haunt ===== Please note that this is a grown code and was not cleaned up at all, its more a proof of concept and I am not even sure if the concept is not nonsense... however, it works for me and if you should be seriously interested it, notify me and I will work a bit on cleaning it. This is a script which wraps itself around an arbitrary python object and then tracks all things done with it (not internal things). This list of things done with it can be saved with pickle even if the object itself cannot be saved easily, and also provides a complete history of what is done with the object in what order. These wrapped objects are called Haunted here... Notes: o There are some smaller things that would not be tracked, but for cleanly written object orientated code that should be almost nothing. (For example if a wrapped object inside a function call passes one of its attributes out, so that it can be changed there lateron -- it does not matter if it would be immidiatly, as then ) o The is operator will fail if there is a not haunted version around, this _could_ happen, but should be mostly avoided by not hindering execution if there is a function call in progress which is tracked. For Matplotlib ============== The pyplot module provides some extra functionality (savesession, figure, loadfigure) on top of matpltlib.pyplot which it extends though you only need to use it for figure creation. Also the resulting figure objects have some extra attributes: o savesession (save figure to file) o loadsession (load figure from file, should be possible to combine figures with) o haunt (Can be used to track complex items that cannot be simply passed in tothe figure and then saved, see Axes3D example.) o get_history (returns the history that was used to create the figure, can be edited, but needs to be loaded into a new figure by hand to take effect) Note that these are not visible in IPythons tab completion because the __dict__ and __members__ are overriden to be the figures. This is sufficient for my purpose of opening a bit more flexible version of images done of parameter scans. I set it up for double click to open and a second option for opening in an IPython shell to be editable... (see scripts figview.py and figedit.py, even if they are hacks :)) Some details ============ For the most part the script seems to work fine. It wills tore quite a bit of extra things, so if you move around in a figure with the mouse and then save it, you will get bloated figures. While it tries to discard some duplicate set events while saving (ie. resizing the figure multiple times), this will most likely not work for many things. While saving all things that are not posisble to be pickled and everything depending on this will be discarted, this is usually not a problem though, but the check for not pickable input should be set earlier to allow tracking the consecutive calls which are right now discareted. As said, during a wrapped function call, no more action are actually tracked and only the real objects passed to avoid bloating, this should typically be no problem unless in some weird program designs. One thing is, that its probably better to do such wrapping/haunting by subclassing (where possible) instead of an extra layer around the object. Axes3D ------ I have not tried many things with this program, but Axes3D toolkit is possible. However it seems that the mouse events to change the view angle/distance are not stored for a 3D Axes, which I guess is because of unpickable objects, and could maybe be fixed by checking earlier if it is pickable or not. Axes3D (and other objects that may otherwise not save) can be used by a script such as this: from mpl_toolkits.mplot3d import Axes3D import haunt.pyplot fig = haunt.pyplot.figure() Axes3D = fig.haunt(Axes3D) # now this Axes3D class is tracked by the figure # As it is tracked, its initialization is tracked too (and the figure is passed # into it as the normal figure object and nothing weird (actually probably only # important because of a single assert in my version of matplotlib which uses # the is operator) ax = Axes3D(fig) # ax is returned by a haunted/wrapped call, so it is wrapped too, you can now # do everything fine with it: ax.plot3D(np.random.random(100), np.random.random(100), np.random.random(100), ',') fig.savesession('test') haunt.pyplot.loadfigure('test')