PlotBasics

From CASA Guides
Jump to navigationJump to search

The Three Ways to plot

There are three ways to go about plotting in matplotlib.

1. You can use the pylab environment

2. You can use the matplotlib.pyplot environment, with plotting commands and functions.

3. You can define plot objects, and then use the pyplot methods on those objects.

The last way gives you most control, but the other two are somewhat easier. TheSupernova_Cosmology_Example below uses method 2.

Supernova Cosmology Example

  1. We will import the pyplot and numpy packages
import numpy as np
import matplotlib.pyplot as plt

Reading Data from the Web

We are going to download data from the internet so we will import the urllib package

import urllib

Begin by reading the Union2 SN cosmology data from LBL, because they are fun.

SN_list = ['']          
z_array = np.array([])
mod_array = np.array([])
moderr_array = np.array([])
f = urllib.urlopen('http://supernova.lbl.gov/Union/figures/SCPUnion2_mu_vs_z.txt')
for line in f:
    if line[0] == '#': continue    # Ignore anything that starts with a #
    SN, z, mod, moderr = line.split()
    SN_list.append(SN)
    z_array = np.append(z_array,np.float64(z))
    mod_array = np.append(mod_array,np.float64(mod))
    moderr_array = np.append(moderr_array,np.float64(moderr))   
f.close()

Simple Plots

Now to the plotting. First we close whatever windows we might have:

plt.close()

Now let us plot some points:

plt.plot(z_array, mod_array)

Notice it is a mess; by default it connects the lines. We will close it and start over.

plt.close()

We clearly need a title and axes labels

plt.title("Union2 SN Cosmology Data")
plt.xlabel('z', fontsize=20)

But we want a Greek Letter, so we can put some LaTeX syle code with the r command:

plt.ylabel(r'$\mu=m-M$', fontsize=20)

Now we add a format string to the plot command:

plt.plot(z_array, mod_array,'ro')

Now this looks better, we have red circles.

Now we start a new plot:

plt.close()

Plotting with Error Bars

Now let's plot with the error bars

plt.errorbar(z_array, mod_array, yerr=moderr_array, fmt='.')

And putting labels and colors we can do:

plt.xlabel(r'$z$', fontsize=20)
plt.ylabel(r'$\mu=m-M$', fontsize=20)
plt.title("Union2 SN Cosmology Data")
plt.errorbar(z_array, mod_array, yerr=moderr_array, fmt='.', capsize=0,
    elinewidth=1.0, ecolor=(0.6,0.0,1.0), color='green' )

Notice that colors can be specified with a fmt a color keyword. They can be given via an RGB tuple, an RGB hex code, a name, or a single number between 0 and 1 for gray scale.

plt.close()

Plotting Histograms

Now there are a lot of points, so let's figure our what our distribution is in z:

plt.hist(z_array, 25)
# And slap a label on it
plt.xlabel(r'$z$', fontsize=20)
plt.close()

Plotting With Asymmetrical Error Bars

Now, let's find the real distance from the distance modulus. To do this we will define a function and a constant.

def distance_Mpc(m,z):
    return 0.00001 * (10**(m/5)) / (1.0 + z)
c = 299792.458    # km/s


d_array = distance_Mpc(mod_array,z_array)

Now we will calculate the error bars in the distance, both ways:

d_error_plus  = ( distance_Mpc((mod_array+moderr_array),z_array) - d_array )
d_error_minus = ( d_array - distance_Mpc((mod_array-moderr_array),z_array) )

And plot the graph with asymetrical horizontal error bars, and labels Notice the different color formats that can be used.

plt.errorbar(d_array, z_array, xerr=(d_error_minus,d_error_plus), fmt='s',
    capsize=5, elinewidth=1.0, color=(0.4,0.0,1.0), ecolor='aqua', barsabove=True)
plt.ylabel('z', fontsize=15, color='0.0')
plt.xlabel('Distance (Mpc)', fontsize=10, color='g')
plt.title("Union2 SN Cosmology Data", color=(0.4,0.0,1.0))
plt.close()

Plotting With Multiple Axes

Now imagine we want to make a plot for the public, so we need to find the distance in light years. Also, we want to plot cz.

d_array       = 3.26*d_array       # Convert to Mly
d_error_minus = 3.26*d_error_minus # Convert to Mly
d_error_plus  = 3.26*d_error_plus  # Convert to Mly

Now we will plot them in Billions of light years.

plt.errorbar(d_array/1000.0, c*z_array, xerr=(d_error_minus/1000.0,d_error_plus/1000.0),
    fmt='.', capsize=0, elinewidth=1.0, color=(0.4,0.0,1.0), ecolor='aqua', barsabove=False)

Now we make room for each axis

plt.subplots_adjust(right=0.875, top=0.8)

And plot the labels.

plt.ylabel('cz (km/s)', fontsize=15, color='aqua')
plt.xlabel('Distance (Billions of Light Years)', fontsize=15, color='aqua')

Now, you want to make the plot also include z and Mpc, so we need to convert our axes:

axes1_range = np.array( plt.axis() )  # get the existing axes and convert to n array
print(axes1_range)
axes2_range = 1.0*axes1_range  # Don't forget, we need to make a copy of it.
axes2_range[0:2] = 1000*axes1_range[0:2]/3.26  # set second x-axis to Mpc  
axes2_range[2:4] = axes1_range[2:4]/c # set second y-axis to z
print(axes2_range)

Now we switch to the second axis

plt.twinx()   #  This swaps the Y axis
plt.ylabel('z', fontsize=15, color='r')  #  I am not sure why this has to be before plt.twiny()
plt.twiny()   #  This swaps the X axis 
plt.xlabel('Distance (Mpc)', fontsize=15, color='purple')
plt.axis(axes2_range, axisbg='#d0,1f,ff')
plt.title("Union2 SN Cosmology Data", color=(0.4,0.0,1.0), x=0.5, y=1.15)

Saving as a PDF

We can save a file as a PDF or most any other common format this way:

plt.savefig('Union2_plot.pdf', format="pdf", transparent=True, bbox_inches='tight')

It is important to note that some file formats are raster graphics and others are scalable vector graphics.