next up previous
Next: Reporting bugs Up: IPython An enhanced Interactive Previous: Extensions for syntax processing


Access to Gnuplot

Through the magic extension system described in sec. 5.1, IPython incorporates a mechanism for conveniently interfacing with the Gnuplot system (http://www.gnuplot.vt.edu). Gnuplot is a very complete 2D and 3D plotting package available for many operating systems and commonly included in modern Linux distributions.

Besides having Gnuplot installed, this functionality requires the Gnuplot.py module for interfacing python with Gnuplot. It can be downloaded from: http://gnuplot-py.sourceforge.net.

The numeric IPython profile, which you can activate with 'ipython -p numeric' will automatically load the IPython Gnuplot extensions (plus Numeric and other useful things for numerical computing), contained in the GnuplotMagic module. You can also load this module at any time while using IPython via an 'import GnuplotMagic' command. This will create the globals Gnuplot (the standard Gnuplot module) and g (a Gnuplot active instance) and the new magic commands @gp and @gp_set_instance.

Below is a copy of the file which implements these5. This file can be used as an example for writing sub-systems for interfacing to any other program from within IPython, such as talking to Mathematica.

In the numutils module (available via 'import IPython.numutils') you'll also find the gnuplot_exec() function which is useful for passing multi-line strings (such as those generated in Gnuplot via the save command) to a Gnuplot instance. This function is not in GnuplotMagic because that module only works inside IPython.

Gnuplot extensions file (loaded in the numeric profile by importing the GnuplotMagic module):


"""Magic function system for convenient interfacing with Gnuplot.

Warning: This module can ONLY be imported inside IPython or through an
embedded IPython instance.

This requires the Gnuplot.py module for interfacing python with gnuplot. It
can be downloaded from:

http://gnuplot-py.sourceforge.net/

This system builds the magic functions:

@gp -> pass one command to gnuplot and execute them or open a gnuplot shell
where each line of input is executed.

@gp_set_instance -> see below.

and global variables:

- g: pointing to a running gnuplot instance.
- Gnuplot: the Gnuplot module.

The docstrings below contain more details.

Please note that all commands are executed in the gnuplot namespace, so no
python variables exist there. Any data communication has to be done via files,
or using the methods of the gnuplot instance directly. For convenience, a copy
of the internal gnuplot instance called 'g' is created for you at startup. You
can call whichever methods you need on g (try typing g.<TAB> to see a list of
g's methods, or see the documentation for the Gnuplot.py module for details).

Configure this file's behavior by setting the global variable 'gnuplot_mouse'.

Inspired by a suggestion/request from Arnd Baecker."""

# If you have a mouse-enabled gnuplot, you can set gnuplot_mouse to 1,
# otherwise leave it at 0. Unfortunately there's no way to currently catch the
# resulting error message as a python exception if this doesn't work, so I
# can't leave it permanently on.

# Please note that this feature may cause some hiccups in communication with
# the gnuplot process (requiring sometimes a command to be issued twice). This
# is discussed in the gnuplot help and is an issue beyond my control. If it
# becomes a problem, resign yourself to not using the mouse features in
# gnuplot through IPython.

gnuplot_mouse = 0

# Create the Gnuplot instance we need
import Gnuplot

__IPYTHON__.gnuplot = Gnuplot.Gnuplot()
__IPYTHON__.gnuplot.shell_first_time = 1
g = __IPYTHON__.gnuplot  # alias for interactive convenience

# Force g as a global in IPython's namespace if we're being imported
if __name__ == 'GnuplotMagic':
    __IPYTHON__.user_ns['g'] = g
    __IPYTHON__.user_ns['Gnuplot'] = Gnuplot

if gnuplot_mouse:
    g('set mouse')
    print "*** g is a global alias to the internal Gnuplot instance (mouse enabled)."
else:
    print "*** g is a global alias to the internal Gnuplot instance."
print "*** Gnuplot instance access via @gp, or by calling methods of g directly."
print "*** Gnuplot module has been exported as a global."

# Define the magic functions for communicating with the above gnuplot instance.
def magic_gp(self,parameter_s=''):
    """Execute a gnuplot command or open a gnuplot shell.

    Usage (omit the @ if automagic is on). There are two ways to use it:

      1) @gp 'command' -> passes 'command' directly to the gnuplot instance.

      2) @gp -> will open up a prompt (gnuplot>) which takes input until '.'
      is entered (without quotes), or ^C or ^D are pressed. Each line of input
      is given to gnuplot as a command to be executed. If you need to type a
      multi-line command, use \\ at the end of each intermediate line.

      IPython traps the following forms of gnuplot's termination command:
      'quit' and 'exit', and simply returns to IPython without killing the
      gnuplot process. But if you type another form accepted by gnuplot,
      you'll terminate gnuplot (see below for how to restart it). So in order
      to simply return to IPython, use only one of the following exit options:
      '.', 'quit','exit', ^D (EOF) or ^C.

      Upon exiting of the gnuplot sub-shell, you return to your IPython
      session (the gnuplot sub-shell can be invoked as many times as needed).

    This system relies on the existence of a user-level variable called
    __gnuplot pointing to an active Gnuplot session. This variable is
    automatically created at startup, but if you overwrite it the system will
    stop functioning. You can create it again with a call like:

    In [1]: __gnuplot = Gnuplot.Gnuplot()    """

    from IPython.genutils import raw_input_ext

    if parameter_s.strip() == '':
        try:
            self.shell.gnuplot.has_run
        except AttributeError:
            print \
"""To exit gnuplot and return to IPython: '.', 'quit', 'exit', ^C or ^D (EOF).
Use \\ to break multi-line commands."""
            self.shell.gnuplot.has_run = 1
        try:
            cmd = raw_input_ext('gnuplot> ','more...> ')
            while cmd.strip() not in ['.','quit','exit']:
                self.shell.gnuplot(cmd)
                cmd = raw_input_ext('gnuplot> ','more...> ')
        except (EOFError,KeyboardInterrupt):
            pass
    else:
        self.shell.gnuplot(parameter_s)


def magic_gp_set_instance(self,parameter_s=''):
    """Set the global gnuplot instance accessed by the @gp magic function.

    @gp_set_instance name

    Call with the name of the new instance at the command line. If you want to
    set this instance in your own code (using an embedded IPython, for
    example), simply set the variable __IP.gnuplot to your own gnuplot
    instance object."""
    
    self.shell.gnuplot = eval(parameter_s)


# Add the new magic functions to the class dict
from IPython.iplib import InteractiveShell
InteractiveShell.magic_gp = magic_gp
InteractiveShell.magic_gp_set_instance = magic_gp_set_instance

# Keep global namespace clean
del magic_gp,magic_gp_set_instance,gnuplot_mouse

#********************** End of file <GnuplotMagic.py> *********************

You can also use Gnuplot as part of your normal Python programs. Below is some example code which illustrates how to configure Gnuplot inside your own programs but have it available for further interactive use through an embedded IPython instance. Simply run this file at a system prompt. This file is provided in your IPYTHONDIR as example-gnuplot.py:


#!/usr/bin/env python
"""
Example code showing how to use gnuplot and an embedded IPython shell.
"""

import Gnuplot
from Numeric import *
from IPython.numutils import *
from IPython.Shell import IPythonShellEmbed

# Arguments to start IPython shell with. Load numeric profile.
ipargs = '-profile numeric' 
ipshell = IPythonShellEmbed(ipargs)

# Compute sin(x) over the 0..2pi range at 100 points
x = frange(0,2*pi,npts=200)
y = sin(x)

# Make a gnuplot instance
g2 = Gnuplot.Gnuplot()

# Change some defaults
g2('set data style lines')

# Or also call a multi-line set of gnuplot commands on it:
gnuplot_exec(g2,"""
set xrange [0:pi]     # Set the visible range to half the data only
set title 'Half sine' # Global gnuplot labels
set xlabel 'theta'
set ylabel 'sin(theta)'
""")

# Set the gnuplot instance accessed by @gp to our customized one. This way the
# interactive system @gp will see our instance with whatever changes we've
# made to it.
ipshell.IP.gnuplot = g2

# Now start an embedded ipython. g2 is a visible global, but it's also the one
# accessed by @gp now
ipshell('Starting the embedded IPyhton.\n'
        'Try calling g2.plot(zip(x,y)), or "@gp plot x**2"\n')

#********************** End of file <example-gnuplot.py> *********************


next up previous
Next: Reporting bugs Up: IPython An enhanced Interactive Previous: Extensions for syntax processing
Fernando Perez 2002-04-29