6

I use QGIS and have a geological map for a large area. I present this after ID codes based on the geology ("Geokartnr" in photo).

I want to use international/nation color codes for each rock type, this way it will be comparable to other peoples work. The international colors is already added to the attribute table as a RGB code ("RGBfargko"). Is there any way I can sort/present the maps by "geokartnr" code and present this by the color codes in the RGB codes in the attribute table? Or do I need to change all colors manually?

Screenshot of the attribute table

4
  • 1
    Be aware that by using an expression to set the color as stated answer below you wont be able to automatically generate a legend.... (so the problem is you either set the color manually OR create the legend manually....)
    – J.R
    Commented Mar 21, 2019 at 10:00
  • @J.R Good point, I think its kind of bug, because I suppose that it will generate legend if you use Categorized symbology (with rgb field as category). You can manually change a symbol of every each category, but if the data defined values are set for color, the value is just not taken from the expression. Or I am missing something?
    – Oto Kaláb
    Commented Mar 21, 2019 at 11:08
  • I found there is a way to update both the symbology itself, and the colours in the legend. I did it in August. But sadly I can't find it anymore now! Does anybody know how to update both the legend and polygons based on rgb values from my table? Commented Dec 18, 2019 at 14:50
  • i have same question what you saied is good and work but when i want to save that as SLD it do not work and it save only default Style That would be very nice if you can help me Commented May 29, 2020 at 8:05

4 Answers 4

10

In the layer styles panel if you click on simple marker, there is a small box to the right of the fill color combo box - if you click on it you can select edit from the menu and enter the expression editor.

enter image description here You will need an expression like this, to convert your string's spaces to commas and then into a colour:

color_rgb( replace("rgbfargeko",' ',','))

Then click ok and your colors should show up.

0
7

AS @J. Monticolo supposed, use Data defined expression in symbology properties.

enter image description here

For expression you can simply use:

replace("rgbfargko",' ',',')

Which takse "rgbfargko" string and replace spaces whit commas for proper color formatting. See:

enter image description here

enter image description here

4

In the layer properties, in the symbology tab, define the color by an expression (link to the QGIS doc) :

color_rgb(
    array_get(string_to_array("rgbfargko", ' '), 0),
    array_get(string_to_array("rgbfargko", ' '), 1),
    array_get(string_to_array("rgbfargko", ' '), 2)
)

Explanation of the code :

1- function string_to_array : transform the field data into an array by splitting at the white space character ; 2- function array_get : get elements of the array, the first item has an index of 0 ; 3- function color_rgb : with 3 arguments (R, G, B), this function return a QGIS color.

EDIT The solution of @Ian Turton is more visual and simple !

1

I have an attribute table with fields:

  • Stratname - stratigraphic name of unit
  • RGB colour fields
  • Red
  • Green
  • Blue

I found this script somewhere, (slightly modified by myself) and run it in the Python plugin window in QGIS. The first few lines define the index of the above fields and then applies it to change the renderer's symbol colours. You can easily separate your RGB code into Red, Green, and Blue fields. I guess you can also change the program to read the RGB code directly from the attribute table, but I have not come to that.

The script reads:

# The fields of importance are 
#STRATNAME Field Index=Strat_idx 
#Red  Field Index=Red_idx
#Green Field Index=Green_idx 
#Blue Field Index=Blue_idx 

from PyQt5 import QtGui
layer = iface.activeLayer()

#Get fields matrix
fields= layer.fields()

#Find field numbers for fields used in rendering
strat_idx= layer.fields().indexFromName('STRATNAME')
print('StratName: ',strat_idx)

# Can also use indexOf(fieldname) to find field number 
Red_idx= layer.fields().indexOf('Red')
print('Red: ',Red_idx)

Green_idx= layer.fields().indexFromName('Green')
print('Green: ',Green_idx)

Blue_idx= layer.fields().indexFromName('Blue')

print('Blue: ',Blue_idx)

MyRenderer=layer.renderer()

#define the categories array that contain the unique-renderer values
categories = MyRenderer.categories()

#define the array that will contain the number of variables for #the renderers
#and the number of unique values in the legend

#print (len(categories)) #Number of legend items 

Matrix = [[0 for x in range(4)] for x in range(len(categories))]

#initialise the counter
ind=0
for category in categories:
#  print category.value()#
  Matrix[ind][0]=category.value()
  #print('index:',ind,' ', Matrix[ind][0]) #
  ind=ind+1

iter = layer.getFeatures()
# retrieve every feature with its attributes 
for feature in iter:

# fetch attributes

  for index in range(len(Matrix)):
    if feature[strat_idx] == Matrix[index][0]:
      #print('ok')
      Matrix[index][1]=feature[Red_idx]
      Matrix[index][2]=feature[Green_idx]
      Matrix[index][3]=feature[Blue_idx]
      break

    #Classification variable =featur[0]
    #col_R=feature[1]
    #col_G=feature[2]
    #col_B=feature[3]
 
for category in categories:
  for index in range(len(Matrix)):
    if category.label() == Matrix[index][0]:
        colR=int(Matrix[index][1])
        colG=int(Matrix[index][2])
        colB=int(Matrix[index][3])
        category.symbol().setColor(QColor.fromRgb(colR,colG,colB))
        #Set the outline color transparent
        category.symbol().symbolLayer(0).setStrokeColor(QColor('#00000000'))      
        
expresssion='STRATNAME'
renderer = QgsCategorizedSymbolRenderer(expresssion, categories)
layer.setRenderer(renderer)
layer.triggerRepaint()

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.