4
############################
5
Exploring Chaco with IPython
6
############################
8
Chaco has an interactive plotting mode similar to, but currently more limited
9
than matplotlib's. This plotting mode is also available as an Envisage plugin,
10
and so can be made available within end-user applications that feature an
11
Envisage-based Python prompt.
16
To get started, you need to run iPython with the ``--gui=wx`` option enabled,
17
so that the iPython and wx event loops interact correctly [#guiqt]_ ::
21
You could instead start in ``-pylab`` mode if you prefer, which has the advantage of
22
pre-loading numpy and some other useful libraries.
23
Once you have the iPython prompt, you can accesss the Chaco shell mode commands
26
In [1]: from chaco.shell import *
28
We'll start by creating some data that we want to plot::
30
In [2]: from numpy import *
31
In [3]: x = linspace(-2*pi,2*pi, 100)
35
.. image:: images/ipython_basic.png
37
If you experiment with the plot, you'll see that it has the standard
38
Chaco pan and zoom tools enabled. As with Matplotlib, you can specify
39
options for the display of the plot as additional arguments and keyword
40
arguments to the plot command. The most important of these is is the
41
format string argument, which resembles the Matplotlib format strings::
43
In [6]: plot(x, y, 'g:')
45
This creates a green, dotted line plot of the data. You could instead
46
create a red scatter plot of the data with circles for markers using::
48
In [7]: plot(x, y, 'ro')
50
You'll notice that each of these plot commands replaces the current plot
51
with the new plot. If you want to overlay the plots, you need to instruct
52
Chaco to ``hold()`` the plots::
55
In [9]: plot(x, cos(x), 'b-')
56
In [10]: plot(x, sin(2*x), 'y^')
58
.. image:: images/ipython_multi.png
60
Calling ``hold()`` again will toggle back to the previous
65
You can also plot multiple curves with one plot command. The following
66
single plot call is equivalent to the above three::
68
In [12]: plot(x, y, 'ro', x, cos(x), 'b-', x, sin(2*x), 'y^')
73
The Chaco shell interface supports a subset of the standard Chaco plots.
74
You can do line, scatter, image, pseudocolor, and contour plots.
76
To illustrate some of these different plot types, let's create a couple
77
of 2D gaussians and plot them::
79
In [13]: x1 = random.normal(-0.5, 1., 100)
80
In [14]: y1 = random.normal(-1.25, 0.5, 100)
81
In [15]: x2 = random.normal(0 ,0.25, 50)
82
In [16]: y2 = random.normal(0, 0.5, 50)
83
In [17]: plot(x1, y1, 'ro', x2, y2, 'go')
85
We'll now create a kernel density estimator for the combined data set,
88
In [18]: x = concatenate((x1, x2))
89
In [19]: y = concatenate((y1, y2))
90
In [20]: dataset = array([x, y])
91
In [21]: import scipy.stats
92
In [22]: kde = scipy.stats.gaussian_kde(dataset)
94
Now that we have the distribution, we sample it at a bunch of points on a grid::
96
In [23]: xs = linspace(-4, 4, 100)
97
In [24]: ys = linspace(-4, 4, 100)
98
In [25]: xpoints, ypoints = meshgrid(xs, ys)
99
In [26]: points = array([xpoints.flatten(), ypoints.flatten()])
100
In [27]: z = kde(points)
101
In [28]: z.shape = (100, 100)
103
Finally, we can plot the contours. For grid-based plots like contours and images,
104
we need to supply the x- and y-coordinates of the edges of the pixels, rather than
107
In [29]: xedges = linspace(-4.06125, 4.06125, 101)
108
In [30]: yedges = linspace(-4.06125, 4.06125, 101)
110
In [32]: contour(xedges, yedges, z)
112
.. image:: images/ipython_kde.png
114
Other related plotting commands which are available include ``imshow()``, ``contourf()``
115
and ``pshow()``. For example::
117
In [33]: pshow(xedges, yedges, z)
119
will plot a pseudo-color image of our sampling of the KDE.
124
You can add plot and axis titles to your plot easily::
126
In [34]: title('The Kernel Density Estimator')
130
and you can toggle whether or not grids are drawn by::
139
toggles the display of the legend. These toggling commands can optionally take a
140
boolean value which instead of toggling the display will either always show or hide
141
the grid or legend. For example::
143
In [40]: legend(False)
145
will ensure that the legend is hidden. You can toggle the axes completely with::
150
but you can additionally gain quite fine-grained control over display of the axes
151
by passing keyword arguments to these commands. For example, to display the y-axis
152
on the right instead of the left, you would do::
154
In [43]: yaxis(orientation='right')
156
You can see the complete set of available keyword arguments via ipython's help::
159
Base Class: <type 'function'>
160
String Form: <function yaxis at 0x1e4e25f0>
161
Namespace: Interactive
162
File: /Users/cwebster/src/ets/chaco/enthought/chaco/shell/commands.py
163
Definition: yaxis(**kwds)
165
Configures the y-axis.
169
* ``yaxis()``: toggles the vertical axis on or off.
170
* ``yaxis(**kwds)``: set parameters of the vertical axis.
175
The text of the title
176
title_font : KivaFont('modern 12')
177
The font in which to render the title
178
title_color : color ('color_name' or (red, green, blue, [alpha]) tuple)
179
The color in which to render the title
184
If you have a plot in a state that you are happy with, you can save the current
185
image with the ``save()`` command::
187
In [45]: save('my_plot.png')
189
Log Plots and Time-Series
190
=========================
192
The Chaco ipython shell can create plots with logarithmic axes. If you know at the time
193
that you create the plot that you want log axes, you can use one of the commands
194
``semilogx()``, ``semilogy()`` or ``loglog()`` as you would the usual ``plot()`` command::
196
In [46]: x = linspace(0, 10, 101)
197
In [47]: y = exp(x**2)
198
In [48]: semilogy(x, y)
200
If you have already created a plot, and you decide that it would be clearer with a
201
logarithmic scale on an axis, you can set this with the `xscale()` and `yscale()`
204
In [49]: xscale('log')
206
You can set it back to a linear scale in the same way::
208
In [50]: xscale('linear')
210
Time axes are handled in a similar way. Chaco expects times to be represented as
211
floating point numbers giving seconds since the epoch, the same as ``time.time()``.
212
Given a plot with a set of index values expressed as times in this fashion, you
213
can specify the scale as ``'time'`` and Chaco will display tick marks on the axis
216
In [51]: x = linspace(time.time(), time.time()+7*24*60*60, 360)
217
In [52]: y = random.uniform(size=360)
219
In [54]: xscale('time')
224
In addition to the ``hold()`` command discussed earlier, there are several commands
225
that you can use to control the creation of new Chaco windows for plotting in to,
226
and determining which one is currently active::
228
In [55]: figure('fig2', 'My Second Plot')
230
creates a new window with the identifier ``'fig2'`` which will have "My Second Plot"
231
displayed as the title of the window. Any new plots after this command will appear
232
in this window. You can switch to an existing window using the ``activate()`` command,
233
referring to the window either by index or name::
237
will make the original plot window the current window, while::
239
In [57]: activate('fig2')
241
will switch back to our second window.
243
For advanced users, you can get a reference to the current Chaco plot object using the
244
``curplot()`` command. When you have this, you then have full access to the programatic
245
Chaco plot API described elsewhere.
247
Finally, you can use the ``chaco.shell`` API from Python scripts instead of interactively
248
if you prefer. In this case, because you do not have ipython around to set up the GUI
249
mainloop with the ``--gui=wx`` option, you need to use the ``show()``
250
command to start the GUI mainloop and display the windows that you have created.
253
.. rubric:: Footnotes
255
.. [#guiqt] Starting from IPython 0.12, it is possible to use the Qt backend
256
with ``--gui=qt``. Make sure that the environment variable ``QT_API``
257
is set correctly, as described `here
258
<http://ipython.org/ipython-doc/dev/interactive/reference.html?highlight=qt_api#pyqt-and-pyside>`_