开发者

Better way to get user input to plot in iPython module?

开发者 https://www.devze.com 2023-03-06 00:47 出处:网络
I have a module to be used in iPython. I\'d like a user to enter everything needed to make a plot- x, y, label, linewidth, etc. 开发者_JAVA技巧

I have a module to be used in iPython.

I'd like a user to enter everything needed to make a plot- x, y, label, linewidth, etc.

开发者_JAVA技巧

So the user might do something like this:

In[1] import this_script
In[2] x=range(0,10)
In[3] y=x
In[4] magically_exposed_function plot(x,y,'r+', linewidth=2)

This means that my function gets the string plot(x,y,'r+', linewidth=2). This can be parsed and the values of x and y found in the iPython namespace using ip.user_ns, but I'm still stuck on what to do with 'r+' and linewidth=2. Ideally I'd like to be able to:

a) import the entire iPython namespace so that I have the values of x and y available and

b) throw the entire string into plot()

As for b), having something like:

plot_string = x, y, 'r+', linewidth = 2
plot(plot_string)

would be ideal, but this does not work as shown above.

Is this possible to do either of these things? Is there a more graceful solution?

Could the user perhaps do plot(x,y), and my code could grab ahold of that plot and edit it?

Any advice on how to handle this situation would be greatly appreciated :)

Thanks! --Erin

[EDIT] A demo of what I'd like to be able to do:

import matplotlib
import wx
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigCanv
from matplotlib.figure import Figure
import IPython.ipapi
ip = IPython.ipapi.get()
import sys

class WrapperExample(wx.Frame):
    def __init__(self, *args, **kwargs):
        wx.Frame.__init__(self, None, -1)
        self.figure = Figure()
        self.axes = self.figure.add_subplot(111)
        self.axes.plot(*args, **kwargs)
        self.canvas = FigCanv(self, -1, self.figure)

def run_me(*args, **kwargs):
    """ Plot graph from iPython
    Example:
    In[1] import script
    In[2] x=range(0,10)
    In[3] y=x
    In[4] run_me x y
    """
    app = wx.PySimpleApp()
    wrap = WrapperExample(*args, **kwargs)
    wrap.Show()
    app.MainLoop()

ip.expose_magic("run_me", run_me)

[EDIT] The following is how I ended up using the wrapper suggested below:

import wx
import matplotlib
from pylab import *
import IPython.ipapi
ip = IPython.ipapi.get()

class MainCanvas(wx.Frame):
    def __init__(self, *args):
        self.figure = plt.figure()
        self.axes = self.figure.add_subplot(111)
        self.axes.plot(*args)
        show()


def run_this_plot(self, arg_s=''):
    """ Run
    Examples
    In [1]: import demo
    In [2]: rtp x y <z> 
    Where x, y, and z are numbers of any type
    """
    args = []
    for arg in arg_s.split():
        try:
            args.append(self.shell.user_ns[arg])
        except KeyError:
            raise ValueError("Invalid argument: %r" % arg)
    mc = MainCanvas(*args)

# Activate the extension
ip.expose_magic("rtp", run_this_plot)


Parsing the actual string is better left to python. Maybe you want to create a wrapper:

real_plot = plot
def my_plot(*args, **kwargs):
    x, y = args[0], args[1]
    ...your extra code here...
    real_plot(*args, **kwargs)
plot = my_plot
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号