You are here: Home / Services / Data Analysis and Visualization / Visualization / Software / NCL / PyNGL / DKRZ PyNGL example filled circles instead of grid cells

DKRZ PyNGL example filled circles instead of grid cells

This example shows how to draw three plots, first plot is a raster contour plot, the second shows the data with value annotations for each grid cell, and the third plot shows filled circles which are sized by a quality variable instead of grid cells.

Examples:

#
#  File:
#    quality_points_per_grid_cell.py
#
#  Synopsis:
#    Draw filled circles instead of grid cells. The size depends on a quality value.
#
#  Category:
#    contour plot
#    polymarker
#
#  Based on DKRZ's NCL example:
#    quality_points_per_grid_cell.ncl
#
#  Author:
#    Karin Meier-Fleischer
#  
#  Date of initial publication:
#    December, 2018
#
#  Description:
#    Draw two plots, first plot is a raster contour plot and the second shows
#    the data using filled circles which are sized by a quality variable.
#
#  Effects illustrated:
#    o  Creating a contour cellFill plot
#    o  Using markers
#    o  Using dummy data
#    o  Create a legend
#    o  Create a labelbar
#    o  Add text
#
#  Output:
#     Two visualizations are produced.     
#
'''
  PyNGL Example:     quality_points_per_grid_cell.py

  -  Creating a contour cellFill plot
  -  Using markers
  -  Using dummy data
  -  Create a legend
  -  Create a labelbar
  -  Add text
 
'''
from __future__ import print_function
import numpy as np
import Ngl,Nio

VALUES =  True                      #-- turn on/off value annotation of first plot
GRID   =  True                      #-- turn on/off the data grid lines of second plot

#-----------------------------------------------------------------------------------
#-- which country to be shown
#-----------------------------------------------------------------------------------
minlat, maxlat =  47.0, 55.0        #-- minimum and maximum latitude of map
minlon, maxlon =   5.0, 16.0        #-- minimum and maximum longitude of map

#-----------------------------------------------------------------------------------
#-- generate dummy data and coordinates
#-- generate lat and lon arrays with named dimensions
#-----------------------------------------------------------------------------------
nlat, nlon = 16, 22
lat = np.linspace(minlat, maxlat, num=nlat)
lon = np.linspace(minlon, maxlon, num=nlon)

#-- generate dummy data with named dimensions
tempmin, tempmax, tempint = -2.0, 2.0, 0.5
temp   = np.random.uniform(tempmin,tempmax,[nlat,nlon])
temp1d = temp.flatten()
ncells = len(temp1d)

#-- generate random dummy quality data
minqual, maxqual = 1, 4

quality   = np.floor(np.random.uniform(minqual,maxqual+0.5,[nlat,nlon])).astype(int)
quality1d = quality.flatten()

#-----------------------------------------------------------------------------------
#-- graphics
#-----------------------------------------------------------------------------------
#-- open workstation
wkres = Ngl.Resources()
wkres.wkBackgroundColor = "gray85"      #-- set background color to light gray

wks = Ngl.open_wks('png','plot_quality_per_cell',wkres)

#-- set color map
colmap = "BlueDarkRed18"
Ngl.define_colormap(wks,colmap)

#-- contour levels and color indices
cmap    = Ngl.retrieve_colormap(wks)
ncmap   = len(cmap[:,0])
levels  = np.arange(tempmin,tempmax+tempint,tempint)
nlevels = len(levels)
colors  = np.floor(np.linspace(2,ncmap-1,nlevels+1)).astype(int)
ncolors = len(colors)

#-----------------------------------------------------------------------------------
#-- contour plot resources
#-----------------------------------------------------------------------------------
res                        =  Ngl.Resources()
res.nglDraw                =  False
res.nglFrame               =  False
res.nglMaximize            =  False             #-- don't maximize plot output, yet
 
res.vpXF                   =  0.09              #-- viewport x-position
res.vpYF                   =  0.95              #-- viewport y-position
res.vpWidthF               =  0.8               #-- viewport width
res.vpHeightF              =  0.8               #-- viewport height
 
res.cnFillMode             = "RasterFill"       #-- use raster fill for contours
res.cnFillOn               =  True              #-- filled contour areas
res.cnLinesOn              =  False  
res.cnLineLabelsOn         =  False  
res.cnInfoLabelOn          =  False  
res.cnLevelSelectionMode   = "ExplicitLevels"   #-- set manual data levels
res.cnLevels               =  levels  
res.cnMonoFillColor        =  False  
res.cnFillColors           =  colors  
 
res.lbBoxMinorExtentF      =  0.15              #-- decrease height of labelbar
res.lbOrientation          = "horizontal"       #-- horizontal labelbar
 
res.mpOutlineBoundarySets  = "National"         #-- draw national map outlines
res.mpOceanFillColor       = "gray90"  
res.mpLandFillColor        = "gray75"  
res.mpInlandWaterFillColor = "gray75"  
res.mpDataBaseVersion      = "MediumRes"        #-- alias to Ncarg4_1
res.mpDataSetName          = "Earth..4"         #-- higher map resolution
res.mpGridAndLimbOn        =  False  
 
res.mpLimitMode            = "LatLon"           #-- map limit mode
res.mpMinLatF              =  minlat-1.0
res.mpMaxLatF              =  maxlat+1.0
res.mpMinLonF              =  minlon-1.0
res.mpMaxLonF              =  maxlon+1.0

res.sfXArray               =  lon
res.sfYArray               =  lat

#-----------------------------------------------------------------------------------
#-- first, we have to draw a contour map in memory to get the level and color values
#-----------------------------------------------------------------------------------
contour = Ngl.contour_map(wks,temp,res)

Ngl.draw(contour)
Ngl.frame(wks)

#-----------------------------------------------------------------------------------
#-- for checking purposes: draw text and markers at data locations  !! this takes long !!
#-----------------------------------------------------------------------------------
if(VALUES):
   txres               =  Ngl.Resources()
   txres.gsFontColor   = "black"
   txres.txFontHeightF =  0.01
   for j in range(0,nlat):
      for i in range(0,nlon):
         m = i+j
         txid = "txid"+str(m)
         txid = Ngl.add_text(wks, contour,""+str(quality[j,i]),lon[i],lat[j],txres)

#-- draw the second plot
Ngl.draw(contour)
Ngl.frame(wks)

#-----------------------------------------------------------------------------------
#-- create third plot
#-----------------------------------------------------------------------------------
#-- clean contour plot and create a new map plot
plot = Ngl.map(wks,res)

#-----------------------------------------------------------------------------------
#-- draw grid lines of data region if set by GRID global variable
#-----------------------------------------------------------------------------------
if(GRID):
   gres             = Ngl.Resources()
   gres.gsLineColor = "black"
   
   for i in range(0,nlat):
      lx  = [minlon,maxlon]
      ly  = [lat[i],lat[i]]
      lid = "lidy"+str(i)
      lid = Ngl.add_polyline(wks,plot,lx,ly,gres) #-- add grid lines to plot
   
   for j in range(0,nlon):
      lx  = [lon[j],lon[j]]
      ly  = [minlat,maxlat]
      lid = "lidx"+str(j)
      lid = Ngl.add_polyline(wks,plot,lx,ly,gres) #-- add grid lines to plot
      
   Ngl.draw(plot)

#-----------------------------------------------------------------------------------
#-- now, create the marker size for each cell# marker sizes for quality 1-4
#-----------------------------------------------------------------------------------
marker_sizes = np.linspace(0.01,0.04,4)
ms_array     = np.ones(ncells,float)            #-- create array for marker sizes depending
                                                #-- on quality1d
for ll in range(minqual,maxqual+1):
   indsize = np.argwhere(quality1d == ll)
   ms_array[indsize] = marker_sizes[ll-1]

#-- marker resources
plmres                    =  Ngl.Resources()
plmres.gsMarkerIndex      =  16                 #-- filled circles

#-- now, create the color array for each cell from temp1d
gscolors = np.zeros(ncells,int)

#-- set color for data less than given minimum value
vlow = np.argwhere(temp1d < levels[0])          #-- get the indices of values less levels(0)
gscolors[vlow] = colors[0]                      #-- choose color

#-- set colors for all cells in between tempmin and tempmax
for i in range(1,nlevels):
   vind = np.argwhere(np.logical_and(temp1d >= levels[i-1],temp1d < levels[i]))  #-- get the indices of 'middle' values
   gscolors[vind] = colors[i]                   #-- choose the colors

#-- set color for data greater than given maximum
vhgh = np.argwhere(temp1d > levels[nlevels-1])    #-- get indices of values greater levels(nl)
gscolors[vhgh] = colors[ncolors-1]              #-- choose color

#-- add the marker to the plot
n=0
for ii in range(0,nlat):
   for jj in range(0,nlon):
      k = jj+ii
      plmres.gsMarkerSizeF =  ms_array[n]       #-- marker size
      plmres.gsMarkerColor =  gscolors[n]       #-- marker color
      plm = "plmark"+str(k)
      plm = Ngl.add_polymarker(wks,plot,lon[jj],lat[ii],plmres) #-- add marker to plot
      n = n + 1

#-----------------------------------------------------------------------------------
#-- add a labelbar to the plot
#-----------------------------------------------------------------------------------
vpx  = Ngl.get_float(plot,"vpXF")               #-- retrieve viewport x-position
vpy  = Ngl.get_float(plot,"vpYF")               #-- retrieve viewport y-position
vpw  = Ngl.get_float(plot,"vpWidthF")           #-- retrieve viewport width
vph  = Ngl.get_float(plot,"vpHeightF")          #-- retrieve viewport height

lbx, lby = vpx, vpy-vph-0.07

lbres                       =  Ngl.Resources()
lbres.vpWidthF              =  vpw              #-- width of labelbar
lbres.vpHeightF             =  0.08             #-- height of labelbar
lbres.lbOrientation         = "horizontal"      #-- labelbar orientation
lbres.lbLabelFontHeightF    =  0.014            #-- labelbar label font size
lbres.lbAutoManage          =  False            #-- we control label bar
lbres.lbFillColors          =  colors           #-- box fill colors  
lbres.lbPerimOn             =  False            #-- turn off labelbar perimeter
lbres.lbMonoFillPattern     =  True             #-- turn on solid pattern
lbres.lbLabelAlignment      = "InteriorEdges"   #-- write labels below box edges

#-- create the labelbar
pid = Ngl.labelbar_ndc(wks, ncolors, list(levels.astype('str')), lbx, lby, lbres)
                        
#-----------------------------------------------------------------------------------
#-- add legend of marker sizes
#-----------------------------------------------------------------------------------
legres                    =  Ngl.Resources()    #-- legend resources
legres.gsMarkerIndex      =  16                 #-- filled dots
legres.gsMarkerColor      = "gray50"            #-- legend marker color

txres                     =  Ngl.Resources()    #-- text resources
txres.txFontColor         = "black"
txres.txFontHeightF       =  0.01
txres.txFont              =  30

x, y, ik  = 0.94, 0.47, 0

for il in range(minqual,maxqual):
   legres.gsMarkerSizeF = marker_sizes[ik]
   Ngl.polymarker_ndc(wks, x, y, legres)
   Ngl.text_ndc(wks, ""+str(il), x+0.03, y, txres)
   y  = y + 0.05
   ik = ik + 1

txres.txFontHeightF = 0.012

Ngl.text_ndc(wks,"Quality",x,y,txres)           #-- legend title

#-----------------------------------------------------------------------------------
#-- add title string
#-----------------------------------------------------------------------------------
xpos   = (vpw/2)+vpx
title1 = "Draw data values at lat/lon location as circles"
title2 = "the size is defined by the quality variable"

txres.txFont        =  21
txres.txFontHeightF =  0.018

Ngl.text_ndc(wks, title1, xpos, 0.96,  txres)
Ngl.text_ndc(wks, title2, xpos, 0.935, txres)
 
#-----------------------------------------------------------------------------------
#-- add center string
#-----------------------------------------------------------------------------------
y = vpy+0.035                               #-- y-position
txcenter = "Quality: min = "+str(quality.min())+"  max = "+str(quality.max())

txres.txFontHeightF = 0.008                 #-- font size for string
txres.txJust        = "CenterCenter"        #-- text justification

Ngl.text_ndc(wks, txcenter, 0.5, y, txres)  #-- add text to wks

#-----------------------------------------------------------------------------------
#-- draw the second plot and advance the frame
#-----------------------------------------------------------------------------------
Ngl.draw(plot)
Ngl.frame(wks)

Results:

Document Actions