Monday, November 17, 2014

Tutorial: Fill between; how to shade area on line graphs

Sometimes when plotting data on simple line graph it is useful to use colors to fill between different curves.  For example, when plotting anomalies it may be helpful to fill the below zero values blue, and the above zero values red (see below figure).  This tutorial will show you how to use the gxout option 'linefill' to fill areas on your x/y graph. 

500mb height anomaly.  Negative values filled blue.

'set gxout linefill' requires two input values, and will fill the space between these value.  It has been used before in previous tutorials here to help you fill in topography for vertical cross sections (see: here for this example).  We will begin by setting up our file and location.  I've been interested in ensemble forecasting recently, so we'll work with the GFS ensemble data.

  'set display color white'
  'set mpdset hires'

  'set t 1 65'
  'set e 1'
  'set lev 500'
  'set lat 44';'set lon -72'

  'set vrange -30 30'

Notice how I only have one varying dimension (time) in this tutorial.  This will allow us to plot a basic line graph, showing the 500mb height anomaly in time.  Now we are ready to move on to plot the data.  We will be plotting the ensemble mean height anomaly.  >0 => Red <0 => Blue

  'set gxout linefill'
  'set lfcols 2 4'
 'd mean(gpa500mb/10.0,e=1,e=21);const(mean(gpa500mb/10.0,e=1,e=21),0,-a)' 

The above code first sets up, then makes the plot.  First use set 'gxout linefill' to get the graphics set up correctly.  The key to getting the different colors is using the command 'set lfcols 2 4'.  What this command does, is set up your plotting environment such that any value greater than the reference value is set to red(2) and anything less than the reference value is set to blue (4).  Once our colors are set, we plot the variable, in this case the ensemble mean 500mb height (divided by 10 to get units: Decameters).

When using the linefill graphics option , you need two inputs separated by a semi-colon.  These values indicate the values that will be filled between.  In this case, the first value is the height anomaly, and the second value uses the const function to set all height anomalies = 0.  So in this case, you are plotting the height anomaly relative to the zero line.  This code will give you the image above.

We can take this one step further.  The 2nd value in the 'linefill' display does not have to be a constant, it can vary.  So to stick with the theme of ensemble prediction, we'll plot the height anomaly again, only now we will fill the + and - 1 standard deviation around the mean.

GFS Ensemble mean Height anomaly and shaded Standard Deviation

The following will produce the above plot.  The method for producing the above plot is very similar to what we just discussed,  only now, instead of using the const function to set the 2nd value in the linefill display, we use two variable values.

   'set lfcols 15 0'
  'd mean(gpa500mb/10.0,e=1,e=21)+sqrt(ave(pow(ave(gpa500mb/10.0,e=1,e=21)-gpa500mb/10.0,2),e=1,e=21));mean(gpa500mb/10.0,e=1,e=21)-sqrt(ave(pow(ave(gpa500mb/10.0,e=1,e=21)-gpa500mb/10.0,2),e=1,e=21))'

Now we fill every value between the first (mean + 1std) and the second (mean - 1std) in gray.  Then to make the plot nicer, we throw on the ensemble mean, and we cap the standard deviation with black lines.

There is one last aspect with linefill, that I feel should be included in this tutorial, and that is how to fill the area under the curve with more than 1 color (see example below).  For this, we use similar code as above, only now we put it in a loop.  Now to do this, it works best if your variable is always greater than zero, due to the way the looping is performed.  So we are going to use total cloud cover as our variable.  Additionally, to save time, I'm only going to take a subset of times from the file, and only a subset of ensembles.

GFS Cloud Cover Multi Color

So to start, we set the range of levels that we want to shade in using bars, then we simply loop through all of the levels, use the linefill display, and simply reset the value in the const function to correspond to each level.

      levs='0 10 20 30 40 50 60 70 80 90'
        'set gxout linefill'
        'set lfcols 'c+1' 0'
        'd mean(tcdcclm,e=1,e=5);const(mean(tcdcclm,e=1,e=5),'subwrd(levs,c)',-a)'

    'set gxout line'
    'set ccolor 3'
    'set cthick 8'
    'd mean(tcdcclm,e=1,e=5)'

The code above uses the subwrd command to grab the value from the "array" levs.  It breaks the loop if you run into the end of the array.  Then the code sets a new fill color, and voila, you have a multi-colored shaded plot.

So that's about all there is to the linefill function.  Hopefully after this tutorial you have a better understanding of how the linefill function works, and what some of it's capabilities are.  Below is a script with the various examples used here.

Download Example Script


  1. can anyone please help me with a grads script to calculate Outgoing Longwave Radiation anomaly index

  2. Hi!! Awesome stuff again, I have recently got into a trouble trying to continue drawing a time serie plot with different color of line. Let me put at this way, imagine you have to draw a line for forecast time after drawing the analysis data (observed) until a specific time, so you need to continue showing the forecast from that time, but to represent that period of time in different color of line graph. Any idea? Thanks in advance.

    1. Good question, I cannot give you an exact answer without playing around with GrADS first, but my initial thought would be to use the 'set vrange2' command to explicitly set the bounds of the x-axis. Then you could set the x-axis range to be the entire period from the start of the observations through to the end of the forecast. Then your call would like something like...

      'set vrange2 't1' 't2
      'd obs'
      'set vrange2 't1' 't2
      'set line 2' ;*For different color
      'd forecast'

      Again, I'm not sure if this would work, but its an idea that you could work off of.

    2. This comment has been removed by the author.

    3. Thanks! Actually, there is an idea here in this link that refers to my question,

      ... Those plots are quite related to this post of yours. The first one represents my whole question at the beginning, despite the fact they are using esembles, which is my real challenge. See the red line, that contains 21different outputs as forecast and also notice that is just one set in time, from the start (with the observations) to the last (ensembles or sphaguetti graph-lines). I hope this webpage can be useful to your future projects in mind.

  3. Its all very wonderfull stuff. Could you help me to draw linefill command to fill the negative value of zonal wind with blue colour and postive value of zonal wind with red colour . I have a time series zonal wind anomlay for 10 years.