Color in Legend not the same as in canvas, when defining through field type value in table
What is the bug or the crash?
When setting the colour of a simple marker through field type the colour in the canvas is changed, but the colour of the simple marker and the thereby the legend is not changed.
Steps to reproduce the issue
- making a csv table of items with columns "Name" and column "RBG" for colours in HTML-Notation,
- linking this table to a point vector layer with column "Name"
- making the symbology of the layer as simple marker with the colour defined through field type column "RGB"
-
the colour in the canvas is the right one, but the colour of the legend has to be changed manually.
- changing symbology to rule-based and classified by "Name" when e.g. having a table of many items this becomes very impractible.
Wouldn't it be good to have the colour of the simple marker and the legend changed when a colour is defined through the field type?
Versions
| QGIS-Version | 3.22.4-Białowieża | QGIS-Codezweig | Release 3.22 |
|---|---|---|---|
| Qt-Version | 5.15.3 | ||
| Python-Version | 3.10.3 | ||
| GDAL-Version | 3.4.1 | ||
| PROJ-Version | 8.2.1 | ||
| EPSG-Registraturdatenbankversion | v10.041 (2021-12-03) | ||
| GEOS-Version | 3.10.2-CAPI-1.16.0 | ||
| SQLite-Version | 3.37.2 | ||
| PostgreSQL-Client-Version | 14.2 (Ubuntu 14.2-1) | ||
| SpatiaLite-Version | 5.0.1 | ||
| QWT-Version | 6.1.4 | ||
| QScintilla2-Version | 2.11.6 | ||
| BS-Version | Ubuntu 22.04.2 LTS | ||
QGIS-Version 3.22.4-Białowieża QGIS-Codezweig [Release 3.22](https://github.com/qgis/QGIS/tree/release-3_22) Qt-Version 5.15.3 Python-Version 3.10.3 GDAL-Version 3.4.1 PROJ-Version 8.2.1 EPSG-Registraturdatenbankversion v10.041 (2021-12-03) GEOS-Version 3.10.2-CAPI-1.16.0 SQLite-Version 3.37.2 PostgreSQL-Client-Version 14.2 (Ubuntu 14.2-1) SpatiaLite-Version 5.0.1 QWT-Version 6.1.4 QScintilla2-Version 2.11.6 BS-Version Ubuntu 22.04.2 LTS
Supported QGIS version
- [ ] I'm running a supported QGIS version according to the roadmap.
New profile
- [ ] I tried with a new QGIS profile
Additional context
No response
What color should it be though? The point of data defined properties is they're dependent on a specific feature. So the legend symbology could use the color of the first feature, but I'm no sure this would be an improvement...
I have a database of tree species and they all should have a different colour, mostly depending on the fruit colour. So it's about 100 different species, in the future probably many more. So when I place a point names Oak it should get the colour of oak, and the legend should read oak with the same colour. And another point should be Apple in a different colour. At the moment the all read the name but they have random colours
The colour in the canvas is the right one but not in the legend
Create one legend entry for each symbol and have the static color be displayed without an expression. The symbol in the legend are an abstraction and not a feature. Since it doesn't have any attribute it will only display default/static colors.
When I add a new species to the table then I have to also add a new one symbol with legend entry in the Vectorlayer. Is there a reason or a case why the symbol in the legend is an abstraction and not a feature? Wouldn't it be better for it to be a feature so the colours in the canvas and the legend are the same?
Is there a way to write a script to update the fill colour/legend colour according to the colour given through field type value?
Confirming that I have the same issue. See screenshot attached. Polygon fill colors are set from columns containing R,G,B integers, and are shown correctly in the canvas (either using color_rgb or color_rgba functions). However, the legend colors do not reflect the canvas colors.
The QGIS project highly values your report and would love to see it addressed. However, this issue has been left in feedback mode for the last 14 days and is being automatically marked as "stale". If you would like to continue with this issue, please provide any missing information or answer any open questions. If you could resolve the issue yourself meanwhile, please leave a note for future readers with the same problem and close the issue. In case you should have any uncertainty, please leave a comment and we will be happy to help you proceed with this issue. If there is no further activity on this issue, it will be closed in a week.
I wrote a script that somewhat fixes the problem for me. I wonde if a function like that could be integrated in QGIS, so that the dynamic value from the csv changes the legend color too.
from qgis.core import ( QgsProject, QgsCategorizedSymbolRenderer, QgsSymbolLayerRegistry, QgsMarkerSymbol, QgsSimpleMarkerSymbolLayer, QgsProperty, QgsExpressionContext, QgsExpression, QgsField, QgsFeatureRequest, QgsRendererCategory )
Define the function to update symbology
def update_symbology(layer_name): # Get the layer by its name layer = QgsProject.instance().mapLayersByName(layer_name)[0]
# Get the renderer
renderer = layer.renderer()
if renderer.type() == 'categorizedSymbol':
# Get the categories
categories = renderer.categories()
# Create a new categorized symbol renderer
new_renderer = QgsCategorizedSymbolRenderer('Name')
# Create a dictionary to store the symbols for each attribute value
symbol_dict = {}
# Iterate through the categories and update the symbol color and size
for category in categories:
# Get the attribute value for the category
attribute_value = category.value()
# Skip the category if the attribute value is missing
if attribute_value is None:
print("kein attribute_value")
continue
# Check if a symbol for the attribute value already exists in the dictionary
if attribute_value in symbol_dict:
symbol = symbol_dict[attribute_value]
else:
# Create a feature request to retrieve the features with the matching attribute value
request = QgsFeatureRequest().setFilterExpression('"Name" = \'' + attribute_value + '\'')
# Get the first feature that matches the request
feature = next(layer.getFeatures(request), None)
# Skip the category if no feature is found
if feature is None:
print("kein featue")
continue
# Get the HTML notation for the color from the feature attributes
html_color = feature['Artentabelle_RGB']
size_expression = feature['Anz.Breite']
# Skip the category if the RGB value or size expression is missing
if html_color is None or size_expression is None:
print("kein html_color oder size_expression")
continue
# Create a new symbol layer with the desired color and size
symbol_layer = QgsSimpleMarkerSymbolLayer()
color = QColor(html_color)
symbol_layer.setColor(color)
symbol_layer.setDataDefinedProperty(
QgsSymbolLayer.PropertySize,
QgsProperty.fromExpression(str(size_expression))
)
# Create a marker symbol with the symbol layer
symbol = QgsMarkerSymbol()
symbol.changeSymbolLayer(0, symbol_layer)
# Store the symbol in the dictionary
symbol_dict[attribute_value] = symbol
# Set the symbol to the category
new_renderer.addCategory(QgsRendererCategory(attribute_value, symbol, str(attribute_value)))
# Set the new renderer to the layer
layer.setRenderer(new_renderer)
# Refresh the layer to reflect the changes
layer.triggerRepaint()
Usage example
layer_name = 'Pflanzen Kopie' update_symbology(layer_name)