This page demonstrates Python tips and tricks that I use in my everyday programming as an atmospheric science graduate student.
-Brian Blaylock

Showing posts with label matplotlib. Show all posts
Showing posts with label matplotlib. Show all posts

Wednesday, April 17, 2019

GOES-16 and GOES-17 Overlay

I have successfully plotted GOES-16 and GOES-17 true color images together on the same plot. GOES16 was plotted first, then the GOES17 layer was added on top.

Details on GitHub:
https://github.com/blaylockbk/pyBKB_v3/blob/master/BB_GOES/Both_GOES16_and_GOES17.ipynb


Monday, April 23, 2018

Tips for Publication-worthy Matplotlib Figures

Matplotlib is the graphical plotting package for Python and is heavily used to create. Here are a few tips to create a publication-quality image in Python. There is nothing worse than seeing a poorly made, blurry, or crowded figure when you read a journal article.

The American Meteorological Society has a document that explains best practices to make your figures. These are good rules of thumb to follow.

  1. Create each figure in its own Jupyter Notebook. I recently learned why Jupyter Notebooks are so amazing...it's a great way to document and cleanly see each step. You can easily share notebooks and upload them to GitHub. They also give you the power to make minor changes and do figure 'touch-ups'. These touch-ups are what will make your figures look amazing. 
  2. Pay attention to the dpi: dpi is the 'dots per inch'. A high dpi will make your images look crisp. Generally, anything less than 150 is ideal for viewing on a web, but for print, you want at least 300 dpi. If you figure is just black and white, use at least 1000 dpi. If it includes shades of grey or colors it is acceptable to bump the dpi down to 600. 
  3. Do not manually resize your picture after it has been created. For example, do not make a large picture, load it into PowerPoint, and then shrink the image. This will distort the image, change the dpi, make lines too thin, and cause all sorts of asthetic problems. It is best to make the image the size you want it to be from the beginning.
  4. Pay careful consideration to label, titles, and legends. You want these to be readable, so pay attention to their font size. In fact, most of the time you can get away with not using a figure title--that is the purpose of the figure caption.
  5. Do not use the `Jet` color map. Jet is just horrible. If you need some convincing, then watch this. You can also read a million other articles why Jet is horrible.
  6. Use colors that make sense. If you are showing two diverging values, like negative-ness and positive-ness of a value, use a diverging color map. If you are illustrating hot temperatures, use red.
  7. Consider the right marker shape.
In general, make your figures look good. It is worth spending extra time to make your figures look good. After all, the pretty pictures in your article are the most-looked-at part of your paper.

Thursday, April 13, 2017

Python Colormaps

Before using the python matplotlib color maps, please read this documentation:
http://matplotlib.org/users/colormaps.html

../_images/lightness_00.png
../_images/lightness_01.png
../_images/lightness_02.png
../_images/lightness_03.png
../_images/lightness_05.png

Monday, October 10, 2016

Plotting maps with a loop: Best Practices

Best practices for plotting data on a map with a loop...

If you want to plot many data sets with different times on a base map, only plot the base map once!

Some psudo code:

fig = plt.figure(1)
ax  = fig.add_subplot(111)

## Draw Background basemap
m = Basemap(resolution='i',projection='cyl',\
    llcrnrlon=bot_left_lon,llcrnrlat=bot_left_lat,\
    urcrnrlon=top_right_lon,urcrnrlat=top_right_lat,)
m.drawcoastlines()
m.drawcountries()
m.drawcounties()
m.drawstates()

# Brackground image from GIS
m.arcgisimage(service='NatGeo_World_Map', xpixels = 1000, dpi=100)

# Add a shape file for Fire perimiter
p4 = m.readshapefile('/uufs/chpc.utah.edu/common/home/u0553130/fire_shape/perim_'+perimiter,'perim',drawbounds=False)

# Plot station locations
m.scatter(lons,lats)
plt.text(lons[0],lats[0],stnid[0])
plt.text(lons[1],lats[1],stnid[1])

for analysis_h in range(1,5):

    # code to get lat/lon and data

    # plot pcolormesh, and colorbar
    PC = m.pcolormesh(lon,lat,data)
    cbar = plt.colorbar(orientation='horizontal',pad=0.05,shrink=.8,ticks=range(0,80,5))

    # plot contour
    CC = m.contour(lon,lat,data)


    # plot HRRR 10-m winds
    WB = m.barbs(lon,lat,u,v,)
    

    ### Before you plot the next loop, remove the data plots
    cbar.remove()                  # remove colorbar
    PC.remove()                    # remove pcolomesh
    WB[0].remove()              #remove wind barbs
    WB[1].remove()              #   (takes two steps)
    for cc in CC.collections:  #remove each line in the contour collection
        cc.remove()

Friday, September 23, 2016

Python Matplotlib subscript

This is how to add subscripts to a string in your matlab plot
See more here: http://matplotlib.org/users/mathtext.html

plt.scatter(cyr_no80,co2_no80,color='k',marker='+',label='points')
plt.title(r'CO$_2$ Concentration, no 1980s')
plt.ylabel(r'CO$_2$ (ppm)')
plt.xlabel('Year')


Tuesday, August 2, 2016

Python Matplotlib Superscript

In scientific notation it is more proper to express fractional units with superscipts like ms^-1 instead of m/s.  To do this in labels in python's Matplotlib there is some special formating you need to do...

plt.ylabel(r'Wind Speed (ms$\mathregular{^{-1}}$)')

this will print "Wind Speed (ms^-1)" with the -1 as a superscript on the ylabel. The \mathregular expression makes the font not a fancy italic font. See here: http://stackoverflow.com/questions/21226868/superscript-in-python-plots


Friday, May 13, 2016

Python Matplotlib available colors

Python's matplotlib defines a bunch of colors you can use in you plots. The way colors look on a computer screen looks different than how it looks when you print it, so you can print out the following page as a reference to what colors are available and what they really look like when printed.

Created using a script from http://stackoverflow.com/questions/22408237/named-colors-in-matplotlib

# plot python colors for printing

import matplotlib.pyplot as plt
import matplotlib.patches as patches
import matplotlib.colors as colors
import math
import matplotlib
for name, hex in matplotlib.colors.cnames.iteritems():
    print(name, hex)
    
width= 8
height= 11

fig = plt.figure(figsize=(width,height))
ax = fig.add_subplot(111)

ratio = 1.0 / 3.0
count = math.ceil(math.sqrt(len(colors.cnames)))
print count
x_count = count * ratio
y_count = count / ratio
x = 0
y = 0
w = 1 / x_count
h = 1 / y_count

for c in sorted(colors.cnames):
    pos = (x / x_count, y / y_count)
    ax.add_patch(patches.Rectangle(pos, w, h, color=c))
    ax.annotate(c, xy=pos,fontsize=10)
    if y >= y_count-1:
        x += 1
        y = 0
    else:
        y += 1
        

plt.yticks([])
plt.xticks([])
plt.savefig('allcolors',bbox_inches='tight',dpi=300)
#plt.show()

Friday, April 29, 2016

Redefine Matplotlib defaults: Plotting Publication Quality Plots

The default python matplotlib settings don't look too good for publication quality work. So here I redefine some of matplotlib's default settings before I make a plot.

(see other parameters you can modify here: http://matplotlib.org/users/customizing.html)

import matplotlib as mpl

# Specify universal figure sizes acceptable for publication
# J.AtmosEnv
#        Figure width     |   Inches wide       
#   ----------------------+---------------------
#   1/2 page (1 column)   |  3.54 in. ( 90 mm)   
#   3/4 page (1.5 column) |  5.51 in. (140 mm)    
#   1   page (2 column)   |  7.48 in. (190 mm)    
#   ---------------------------------------------
# Image Resolution:  line graphs = 1000 dpi
#                    colorfilled = 500 dpi         
#                    web images  = 72 dpi             

label_font  = 10    
tick_font   = 8 
legend_font = 7

width=3.5
height=3

## Reset the defaults
mpl.rcParams['xtick.labelsize'] = tick_font
mpl.rcParams['ytick.labelsize'] = tick_font
mpl.rcParams['axes.labelsize'] = label_font
mpl.rcParams['legend.fontsize'] = legend_font

mpl.rcParams['figure.figsize'] = [width,height] 

mpl.rcParams['grid.linewidth'] = .25

mpl.rcParams['savefig.bbox'] = 'tight'
mpl.rcParams['savefig.dpi'] = 1000

Friday, November 20, 2015

python colormaps

When creating plots it is very important to consider the kind of colormap you wish to display the data in. Some colormaps will emphasize certain features more than others. But other color schemes may be deceiving, particularly the rainbow color scheme. See an example here.

Utah terrain with
viridis color map in matplotlib 2.0
Note: In Matplolib Version 2 the default colormap is a green shade called 'viridis' which is much better than jet (see here).

Python's matplotlib module has many preloaded colormaps you can use in your figures. You can look at the available colormaps here: http://matplotlib.org/examples/color/colormaps_reference.html, but I find that looking at just the color bars makes it difficult to imagine what a real plot might look like. So...I created a terrain plot for Utah at 3 km resolution with each python colormap to help visualize what each of the plot would look like.

To set your plot with the desired colormap, simply use the argument:
cmap=plt.get_cmap('name_of_colormap')

For example:
plt.pcolormesh(x,y,height,cmap=plt.get_cmap('Accent'))

Below are all the available colormaps in matplotlib. It is possible to create your own more info on creating your own here.

Matplotlib Default Colormaps
 










































































Custom Terrain Colormap
It is possible to create your own colormap (click  here).
A custom terrain colormap created using this custom colormap: here.

Luke's Colormaps
From github https://github.com/lmadaus/old_wrf_plotting_scripts/blob/master/coltbls.py. You'll load these differently than the default colormaps, but the following are the different options you can use...