QGIS Color Ramp – How to Preclassify a Color Ramp for an Unknown Range in QGIS

color rampqgisstyle

I have to create a template project in QGIS to be taken into the field by others. The aim is, that the user only enters data but does not have to change styles or anything themselves.

I have a layer that represents different storeys of buildings. The storey number is stored as an attribute. To distinguish them better, I'd like to give different storeys different colours using a color ramp. However, I do not know, how many storeys the buildings recorded in this GIS may have. Given the highest buildings and deepest basements at the moment a range of about -50 to 200 should be sufficient in any case, but the usual numbers will certainly lie between -10 and 10. But I there is now way of telling in beforehand.

Is there a way to create a color ramp, that automatically reclassifies to fit the range given in the attribute column it takes the values from?

Best Answer

You can run this script in the Python Script Editor in QGIS and it will symbolise your layer with a colour ramp based on values in the storeys field.

lyr_name = 'my layer'     # the layer you want to symbolise
ramp_name = 'RdGy'        # can be any of the named colour ramps in QGIS (making a custom ramp is also possible)
value_field = 'storeys'   # the field holding the number of storeys

# get the layer
lyr = QgsProject.instance().mapLayersByName(lyr_name)[0]

# get the 'storeys' field index
idx = lyr.fields().indexFromName(value_field)

# build a colour ramp
default_style = QgsStyle().defaultStyle()
color_ramp = default_style.colorRamp(ramp_name)
color_ramp.invert()    # with the RdGy colour ramp give low number of storeys grey and high number red

# instantiate a default symbol for the layer type
symbol = QgsSymbol.defaultSymbol(lyr.geometryType())

# empty list to store the categorised renderer categories
categories = []

# get a sorted list of unique values from the storeys field and iterate through them
for u in sorted(lyr.uniqueValues(idx)):
    # make a render category for each value (category value, symbol, category label)
    cat = QgsRendererCategory(u, symbol, str(u))
    # append it to the list of categories
    categories.append(cat)

# make a categorised renderer with the list of categories
renderer = QgsCategorizedSymbolRenderer(value_field, categories)

# apply the colour ramp to the renderer
renderer.updateColorRamp(color_ramp)

# apply the renderer to the layer
lyr.setRenderer(renderer)

# refresh the symbology
lyr.triggerRepaint()