Using alpha values to show data density

Thematic maps often use a color ramp based on a single color to show data density. Darker colors show a higher concentration of objects, while lighter colors show lower concentrations. You can use a transparency ramp instead of a color ramp to show density as well. This technique is useful if you want to overlay the density layer on imagery or other vector layers. In this recipe, we'll be using some bear-sighting data to show the concentration of bears over an area. We'll use alpha values to show the density. We'll use an unusual hexagonal grid to divide the area and a rule-based renderer to build the display.

Getting ready

You will need to install the MMQGIS plugin, which is used to build the hexagonal grid using the QGIS Plugin Manager.

You also need to download the bear data from https://geospatialpython.googlecode.com/svn/bear-data.zip, unzip the shapefile, and put it in the ms directory of your qgis_data directory.

How to do it...

We will load the bear data. Then, we will use the MMQGIS plugin to generate the hexagonal grid. Then, we'll use the Processing Toolbox to clip the hexagon to the bear shapefile, and join the shapefile attribute data to the hexagon grid. Finally, we'll use a rule-based renderer to apply alpha values based on bear-sighting density and add the result to the map. To do this, we need to perform the following steps:

  1. First, we import all the libraries we'll need, including the processing engine, the PyQt GUI library for color management, and the MMQGIS plugin:
    import processing
    from PyQt4.QtGui import *
    from mmqgis import mmqgis_library as mmqgis
    
  2. Next, we'll set up the paths for all of our input and output shapefiles:
    dir = "/qgis_data/ms/"
    source = dir + "bear-data.shp"
    grid = dir + "grid.shp"
    clipped_grid = dir + "clipped_grid.shp"
    output = dir + "ms-bear-sightings.shp"
    
  3. Now, we can set up the input shapefile as a layer:
    layer = QgsVectorLayer(source, "bear data", "ogr")
    
  4. We'll need the extent of the shapefile to create the grid as well as the width and height, in map units:
    e = layer.extent()
    llx = e.xMinimum()
    lly = e.yMinimum()
    w = e.width()
    h = e.height()
    
  5. Now, we can use the MMQGIS plugin to generate the grid over the entire shapefile's extent. We'll use a grid cell size of one-tenth of a degree (approximately 6 miles):
    mmqgis.mmqgis_grid(iface, grid, .1, .1, w, h, llx, lly, "Hexagon (polygon)", False)
    
  6. Then, we can clip the grid to the shape of our source data using the Processing Toolbox:
    processing.runalg("qgis:clip",grid,source,clipped_grid)
    
  7. Next, we need to do a spatial join in order to match the source data's attributes based on counties to each grid cell:
    processing.runalg("qgis:joinbylocation",source,clipped_grid,0,"sum,mean,min,max,median",0,0,output)
    
  8. Now, we can add this output as a layer:
    bears = QgsVectorLayer(output, "Bear Sightings", "ogr")
    
  9. Next, we create our rendering rule set as Python tuples, specifying a label, value expression, color, and alpha level for the symbols between 0 and 1:
    rules = (
        ('RARE', '"BEARS" < 5', (227,26,28,255), .2),
        ('UNCOMMON', '"BEARS" > 5 AND "BEARS" < 15', (227,26,28,255), .4),
        ('OCCASIONAL', '"BEARS" > 14 AND "BEARS" < 50', (227,26,28,255), .6),
        ('FREQUENT', '"BEARS" > 50', (227,26,28,255), 1),
    )
    
  10. We then create the default symbol rule renderer and add the rules to the renderer:
    sym_bears = QgsFillSymbolV2.createSimple({"outline_color":"white","outline_width":".26"}) 
    rend_bears = QgsRuleBasedRendererV2(sym_bears)
    root_rule = rend_bears.rootRule()
    for label, exp, color, alpha in rules:
        # create a clone (i.e. a copy) of the default rule
    rule = root_rule.children()[0].clone()
        # set the label, exp and color
    rule.setLabel(label)
    rule.setFilterExpression(exp)
    r,g,b,a = color
    rule.symbol().setColor(QColor(r,g,b,a))
        # set the transparency level
    rule.symbol().setAlpha(alpha)
        # append the rule to the list of rules
    root_rule.appendChild(rule)
    
  11. We remove the default rule:
    root_rule.removeChildAt(0)
    
  12. We apply the renderer to the layer:
    bears.setRendererV2(rend_bears)
    
  13. Finally, we add the finished density layer to the map:
    QgsMapLayerRegistry.instance().addMapLayer(bears)
    

How it works...

The rule-based renderer forms the core of this recipe. However, the hexagonal grid provides a more interesting way to visualize statistical data. Like a dot-based density map, hexagons are not entirely spatially accurate or precise but make it very easy to understand the overall trend of the data. The interesting feature of hexagons is their centroid, which is equidistant to each of their neighbors, whereas with a square grid, the diagonal neighbors are further away.

This image shows how the resulting map will look:

How it works...
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset