next up previous
Next: Algorithms Up: AY575 class notes Previous: Programming

Subsections

Plotting

Interactive plotting vs. subroutine plotting.

TOPCAT

Python matplotlib and IDL.

Basic plots

Line graphs: colors, line styles, limits, labels, multiple data sets on a single plot

Point graphs: colors, point types, limits, labels

Hardcopy

Python

see matplotlib usage Parts of a plot.

tutorial

plot commands

State machine interface:

Line plots:

import matplotlib.pyplot as plt (already done with ipython --matplotlib)
plt.plot(y)
plt.plot(x,y)
plt.plot(x,y,color='red'|'green'|'blue'|'cyan'|'magenta'|'yellow'|'black'|....)
plt.plot(x,y,linestyle='-'|'--'|'-.'|':',linewidth=1)
plt.plot(x,y,drawstyle='steps-mid')  # "histogram" style connect
plt.plot?  # for more options

Point plots:

plt.plot(x,y,marker='o'|'.'|...)
plt.plot(x,y,'r-'|'go'|'b.'|....)

For all sorts of point/marker type, see markers

Error bars:

plt.errorbar(x,y,xerr=xerr,yerr=yerr)
plt.errorbar?  # for more options
where xerr and yerr can be single values to be used for all points, or arrays of values for separate error bar lengths for each point.

Limits and labels:

plt.xlim([xmin,xmax])
plt.ylim([ymin,ymax])
plt.xlabel(label)
plt.ylabel(label)
plt.text(label[0],label[1],label[2])

Hardcopy (note that if you want to make hardcopy plots without having a plotting window opened, don't use ipython, just use python.):

plt.savefig(file)

Alternatively, there is a pyplot object interface, which is claimed to offer more flexibility (e.g., can have multiple plots open):

fig = plt.figure()
ax = fig.add_subplot(1,1,1)
ax.plot(x, y)
ax.set_xlim([xmin,xmax])  # note variant on state method command
ax.set_ylim([xmin,xmax])  # note variant on state method command
plt.set_xlabel(label)     # note variant on state method command
plt.set_ylabel(label)     # note variant on state method command
plt.draw()                # required in object mode to draw plot
plt.show()                # needed to show figure in non-interactive mode
plt.savefig(file)

Many data sets in astronomy are ``multidimensional,", and it can be powerful to display additional information on point graphs using color and point size:

scat=ax.scatter(x,y,c=z,vmin=vmin,vmax=vmax,s=size,cmap=cmap,linewidth=linewidth)

where z and size can be arrays of colors (or values to be scaled using vmin and vmax) and point sizes. If you are mapping a range of z values, the vmin= and vmax= keywords give the minimum and maximum data values; all of your data will be scaled into an 8-bit range between these two values. These will then be displayed in ``color" depending on the color map that is specified; a color map determines what colors are used for each of the scaled data values. The default matplotlib color map is 'jet', which scales things from blue to red, but many different colormaps are available, and it is possible to define your own. Note that there is fair amount of literature and opinion on good choices of color map (see, e.g. here, and that most believe that the default 'jet' colormap is a poor choice!

Exercise: plot isochrone color coded by age, with radius coded by point size

Multipanel plots:

plt.subplot(2,1,1)
plt.plot(x,y)
plt.subplot(2,1,2)
plt.plot(x2,y2)
plt.subplots_adjust([hspace=x],[wspace=x],[sharex=True])
# need to control axis labels?
plt.xticks([])
#alternatively, using axis objects
fit=plt.figure()
ax=fig.add_subplot(2,1,1)
ax.plot(x,y)
# or to get a grid of axes objects in a single command:
f, ax=plt.subplots(ny,nx)
ax[iy][ix].plot(x,y)
ax[iy][ix].set_xticks([])
ax[iy][ix].set_visible(False)

A useful Python command for ``packing" the plots onto the page:

plt.tight_layout()
(also available through the subwindows button on the matplotlib window.

Exercise: plot temperature vs log g, absolute mag on two plots, sharing x axis.

For even more flexibility, see gridspec

Histograms: binning, limits, labels. Python hist

plt.hist(data,[bins=n|bins=binarray])


\begin{shaded}
\textit{
Be comfortable generate different types of plots: point ...
...ams, etc. Be able to choose plot colors, limits, label axes, etc.
}
\end{shaded}

``Image'' plots

It is often the case that you have 3D information, i.e., a variable as a function of two other variables. A common example is an image, which is a array of intensities at a grid of different (x,y) pixel locations. But there are many other possibilities as well, e.g., the value of some function across a 2D parameter space.

3D data/images can be displayed in multiple ways. One such way is to encode the variable as a color or intensity, i.e., visualize the data as an image. In Python, this is done using the imshow command. When you display an image, you are displaying data as a function of each (x, y) pixel position. It is likely that these pixel position represent some physical quantity (e.g., position on the sky, value of some independent variables, etc.), so you may want to associate this physical quantity with the pixel positions; this can be done at the plotting level using the extent= keyword in imshow.

Note that imshow by default may attempt to ``smooth" your image; this behavior can be avoid by using the interpolation='none' keyword.

# generate "unit" grids, note useful numpy.mgrid
y, x = np.mgrid[0:100,0:100]
# alternatively, generate grids with fixed number of points between two values
y, x = np.mgrid[0:5:200j, 3500:5500:200j]
plt.imshow(y,[vmin=],[vmax=],[extent=ymin:ymax,xmin:xmax],[interpolation='none'] )
plt.colorbar

The ``unit" grids can be used to generate functions of two variables, e.g.

r2=x**2+y**2
plt.imshow(r2,[vmin=],[vmax=],extent=[ymin:ymax,xmin:xmax])

Exercise: display vmacro relation across HR diagram. Add isochrone points. Add observed data points.

An alternative way to display 3D images is via a countour plot, e.g. matplotlibcontour plots:

cs=plt.contour(x,y,z)
plt.clabel(cs)


\begin{shaded}
\textit{
Be able to generate a simple image plot from a 2D array of data values.
}
\end{shaded}

Other plots

See matplotlib example page for some sample plots with accompanying source code.

IDL examples

set_plot,'X'
plot,x,y
plot,x,y,color=n ; (nth color in a colortable)
plot,x,y,psym=type 
plot,x,y,psym=10
plot,x,y,psym=10,xrange=[xmin,xmax],yrange=[ymin,ymax]
plot,x,y,psym=10,xtitle=lable
oplot,x,y2
ploterror,x,y,xerr,yerr

Event handling

It can be very useful for a program to be to interact with a plot, i.e., for the program to take some action based on input from the plot. This can be accomplished by setting up an ``event handler," which provides code that responds to events such as mouse click, mouse motion, key press, etc.

See matplotlib event handling

For example, in matplotlib windows, a basic event hander is set up that displays the position of the cursor in the plot window. But this can be extended, e.g.:

fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(x,y)

#define an event handler to work with key presses
def onpress(event):
    print 'key=%s, x=%d, y=%d, xdata=%f, ydata=%f'%(
        event.key, event.x, event.y, event.xdata, event.ydata)

cid = fig.canvas.mpl_connect('key_press_event', onpress)

This prints to screen, but what if you want to get information back to a calling routine? Example: say you are fitting a relation to a data set, and recognize that outliers are throwing the fit off: you want to identify these based on a residual plot. Set up blocking and return of data, e.g.:

def onpress(event):
    ''' the event handler '''
    # define variables as global so that they can be returned
    global button, xdata, ydata
    print 'key=%s, x=%d, y=%d, xdata=%f, ydata=%f'%(
        event.key, event.x, event.y, event.xdata, event.ydata)
    # load the global variables
    button = event.key
    xdata = event.xdata
    ydata = event.ydata
    # once we have an event, stop the blocking
    fig.canvas.stop_event_loop()

def mark() :
    ''' blocking routine to wait for keypress event and return data'''s
    # start the blocking, wait indefinitely (-1) for an event
    fig.canvas.start_event_loop(-1)
    # once we get the event, return the event variables
    return button, xdata, ydata

# call the blocking routine
button, xdata, ydata = mark()

Generate random sequence (numpy.random.normal) with an outlier, and identify it from a plot.


next up previous
Next: Algorithms Up: AY575 class notes Previous: Programming
Jon Holtzman 2015-12-11