I'm having problems using a Python function in the expression editor to style a polygon fill in QGIS.
I'm trying to use a random colour scheme. However, I need to do this over a series of different maps from different points in history.
I need the colour for "Norway" to be the same across all maps, likewise the colour should be the same for "Germany". I don't care what the colour is for each country, just that it is consistent between layers.
To do this, I have a Python function which uses the MD5 hash of the column value.
This function works, it looks up an attribute by name and returns an "r,g,b,a" string based on the first 4 bytes of the MD5 hash:-
"""
Define new functions using @qgsfunction. feature and parent must always be the
last args. Use args=-1 to pass a list of values as arguments
"""
from qgis.core import *
from qgis.gui import *
import hashlib
@qgsfunction(args='auto', group='Custom')
def hashcolor(values, feature, parent):
v = feature.attribute(values)
if not v:
v = "Null"
h = hashlib.md5()
h.update(v)
hd = h.hexdigest()
r = int(hd[0:2],16)
g = int(hd[2:4],16)
b = int(hd[4:6],16)
return "{0},{1},{2},255".format(r,g,b)
So for example,
hashcolour('CNTRY')
will always return 213,185,41,255
if the CNTRY field contains "Norway"
I then use this expression as the fill colour for my polygons.
However, I could only get this to work if certain criteria are met:-
- I have labelling turned on for that layer and
- I have used
"CNTRY"
somewhere in the label's expression
I don't want labels, and I can't just use the empty string, so I had to use this hack on the label expression to get it to work:-
regexp_replace("CNTRY", '.*','')
Can anyone explain why I need to use labels in this way to get a python-expression defined colour to work? Is this a bug, or a side-effect of how the expression editor is supposed to work? It seems odd that labelling should be needed to allow polygon styling...
(Setup : Ubuntu Trusty 32-bit, QGIS 2.12.3-Lyon)