Interactive plotting vs. subroutine plotting.
Python matplotlib and IDL.
Line graphs: colors, line styles, limits, labels, multiple data sets on a single plot
Point graphs: colors, point types, limits, labels
Hardcopy
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 optionswhere 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])
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)
See matplotlib example page for some sample plots with accompanying source code.
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
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.
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.