﻿{"id":14527,"date":"2025-07-15T10:00:00","date_gmt":"2025-07-15T08:00:00","guid":{"rendered":"https:\/\/www.sigterritoires.fr\/?p=14527"},"modified":"2025-07-01T10:28:58","modified_gmt":"2025-07-01T08:28:58","slug":"building-an-interactive-dashboard-in-qgis-dynamic-analysis-with-data-plotly-widgets-and-expressions","status":"publish","type":"post","link":"https:\/\/www.sigterritoires.fr\/index.php\/en\/building-an-interactive-dashboard-in-qgis-dynamic-analysis-with-data-plotly-widgets-and-expressions\/","title":{"rendered":"Building an interactive dashboard in QGIS: dynamic analysis with Data Plotly, widgets and expressions"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Objective\"><\/span>Objective<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>Create a dynamic monitoring interface in QGIS with :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Interactive graphs (via Data Plotly)<\/li>\n\n\n\n<li>Simple user filters (range, date, type of waste)<\/li>\n\n\n\n<li>Dynamic key indicators and statistics<\/li>\n\n\n\n<li>A map that adapts to filtered data<\/li>\n<\/ul>\n\n\n\n<p>All without leaving the QGIS interface!<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_82_2 counter-hierarchy ez-toc-counter ez-toc-light-blue ez-toc-container-direction\">\n<div class=\"ez-toc-title-container\">\n<p class=\"ez-toc-title\" style=\"cursor:inherit\">Contenu <\/p>\n<span class=\"ez-toc-title-toggle\"><a href=\"#\" class=\"ez-toc-pull-right ez-toc-btn ez-toc-btn-xs ez-toc-btn-default ez-toc-toggle\" aria-label=\"Toggle Table of Content\"><span class=\"ez-toc-js-icon-con\"><span class=\"\"><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #999;color:#999\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\"><\/path><\/svg><svg style=\"fill: #999;color:#999\" class=\"arrow-unsorted-368013\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\"\/><\/svg><\/span><\/span><\/span><\/a><\/span><\/div>\n<nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/www.sigterritoires.fr\/index.php\/en\/building-an-interactive-dashboard-in-qgis-dynamic-analysis-with-data-plotly-widgets-and-expressions\/#Objective\" >Objective<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/www.sigterritoires.fr\/index.php\/en\/building-an-interactive-dashboard-in-qgis-dynamic-analysis-with-data-plotly-widgets-and-expressions\/#Use_case_monitoring_beach_litter\" >Use case: monitoring beach litter<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/www.sigterritoires.fr\/index.php\/en\/building-an-interactive-dashboard-in-qgis-dynamic-analysis-with-data-plotly-widgets-and-expressions\/#Step_1_Filter_data_interactively\" >Step 1: Filter data interactively<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/www.sigterritoires.fr\/index.php\/en\/building-an-interactive-dashboard-in-qgis-dynamic-analysis-with-data-plotly-widgets-and-expressions\/#Step_2_create_an_interactive_chart_with_Data_Plotly\" >Step 2: create an interactive chart with Data Plotly<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/www.sigterritoires.fr\/index.php\/en\/building-an-interactive-dashboard-in-qgis-dynamic-analysis-with-data-plotly-widgets-and-expressions\/#Step_3_Display_dynamic_indicators_with_labels\" >Step 3: Display dynamic indicators with labels<\/a><ul class='ez-toc-list-level-4' ><li class='ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/www.sigterritoires.fr\/index.php\/en\/building-an-interactive-dashboard-in-qgis-dynamic-analysis-with-data-plotly-widgets-and-expressions\/#Objective-2\" >Objective<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-7\" href=\"https:\/\/www.sigterritoires.fr\/index.php\/en\/building-an-interactive-dashboard-in-qgis-dynamic-analysis-with-data-plotly-widgets-and-expressions\/#Method\" >Method<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-8\" href=\"https:\/\/www.sigterritoires.fr\/index.php\/en\/building-an-interactive-dashboard-in-qgis-dynamic-analysis-with-data-plotly-widgets-and-expressions\/#Result\" >Result<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-9\" href=\"https:\/\/www.sigterritoires.fr\/index.php\/en\/building-an-interactive-dashboard-in-qgis-dynamic-analysis-with-data-plotly-widgets-and-expressions\/#Variant_optional\" >Variant (optional)<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-10\" href=\"https:\/\/www.sigterritoires.fr\/index.php\/en\/building-an-interactive-dashboard-in-qgis-dynamic-analysis-with-data-plotly-widgets-and-expressions\/#Step_4_Organize_the_workspace\" >Step 4: Organize the workspace<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-11\" href=\"https:\/\/www.sigterritoires.fr\/index.php\/en\/building-an-interactive-dashboard-in-qgis-dynamic-analysis-with-data-plotly-widgets-and-expressions\/#In_a_nutshell\" >In a nutshell<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-12\" href=\"https:\/\/www.sigterritoires.fr\/index.php\/en\/building-an-interactive-dashboard-in-qgis-dynamic-analysis-with-data-plotly-widgets-and-expressions\/#Bonus_advanced_tips\" >Bonus: advanced tips<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-13\" href=\"https:\/\/www.sigterritoires.fr\/index.php\/en\/building-an-interactive-dashboard-in-qgis-dynamic-analysis-with-data-plotly-widgets-and-expressions\/#To_be_continued%E2%80%A6\" >To be continued\u2026<\/a><\/li><\/ul><\/nav><\/div>\n\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Use_case_monitoring_beach_litter\"><\/span>Use case: monitoring beach litter<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>Let&rsquo;s take our releves_dechets layer with :<\/p>\n\n\n\n<p>Field Description beach Name of beach type_waste Waste category quantity Quantity observed date_obs Date of observation<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Field <\/th><th>Description<\/th><\/tr><\/thead><tbody><tr><td>beach <\/td><td>Name of beach<\/td><\/tr><tr><td>type_waste<\/td><td>Waste category<\/td><\/tr><tr><td>quantity<\/td><td>Quantity observed<\/td><\/tr><tr><td>date_obs<\/td><td>Date of observation<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>Objective: enable a user to filter data (by range, date\u2026) and immediately see :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>An updated map<\/li>\n\n\n\n<li>A dynamic graph<\/li>\n\n\n\n<li>Updated indicators<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Step_1_Filter_data_interactively\"><\/span>Step 1: Filter data interactively<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Open the layer&rsquo;s attribute table (right-click &gt; \u201cOpen attribute table\u201d).<\/li>\n\n\n\n<li>Click on the funnel icon to activate the filter.<\/li>\n\n\n\n<li>Then click on the filter form icon.<\/li>\n<\/ul>\n\n\n\n<p>The fields will appear with the widgets defined (single values, date range&#8230;). Select the desired values and click on \u201cApply filter\u201d.<\/p>\n\n\n\n<p>This filter does not directly modify the map, but you can :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>use only the entities selected in Data Plotly,<\/li>\n\n\n\n<li>or create a virtual layer with a SELECT * FROM releves_waste WHERE &#8230;.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Step_2_create_an_interactive_chart_with_Data_Plotly\"><\/span>Step 2: create an interactive chart with Data Plotly<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Open the Data Plotly panel (menu View &gt; Panels &gt; Data Plotly).<\/li>\n\n\n\n<li>Choose the chart type (e.g. Bar chart).<\/li>\n\n\n\n<li>Configure :\n<ul class=\"wp-block-list\">\n<li>X Axis: type_dechet<\/li>\n\n\n\n<li>Y Axis: quantity<\/li>\n\n\n\n<li>Layer: your filtered layer<\/li>\n\n\n\n<li>Check Use only selected features if you are filtering via the table.<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<p>As soon as you modify the filter or select other features, the graph is updated.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Step_3_Display_dynamic_indicators_with_labels\"><\/span>Step 3: Display dynamic indicators with labels<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>To avoid complex scripts or temporary views, QGIS lets you display dynamic statistics directly on the map, in the form of labels attached to features.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Objective-2\"><\/span>Objective<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n\n<p>Display, for selected features only :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Beach name<\/li>\n\n\n\n<li>Total waste observed on this range<\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Method\"><\/span>Method<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Activate labels on your layer.<\/li>\n\n\n\n<li>In the label expression, use :<\/li>\n<\/ul>\n\n\n<div class='stb-container stb-style-download stb-caption-box'><div class='stb-caption'><div class='stb-logo'><img class='stb-logo__image' src='data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAACXBIWXMAAAsTAAALEwEAmpwYAAAKT2lDQ1BQaG90b3Nob3AgSUNDIHByb2ZpbGUAAHjanVNnVFPpFj333vRCS4iAlEtvUhUIIFJCi4AUkSYqIQkQSoghodkVUcERRUUEG8igiAOOjoCMFVEsDIoK2AfkIaKOg6OIisr74Xuja9a89+bN\/rXXPues852zzwfACAyWSDNRNYAMqUIeEeCDx8TG4eQuQIEKJHAAEAizZCFz\/SMBAPh+PDwrIsAHvgABeNMLCADATZvAMByH\/w\/qQplcAYCEAcB0kThLCIAUAEB6jkKmAEBGAYCdmCZTAKAEAGDLY2LjAFAtAGAnf+bTAICd+Jl7AQBblCEVAaCRACATZYhEAGg7AKzPVopFAFgwABRmS8Q5ANgtADBJV2ZIALC3AMDOEAuyAAgMADBRiIUpAAR7AGDIIyN4AISZABRG8lc88SuuEOcqAAB4mbI8uSQ5RYFbCC1xB1dXLh4ozkkXKxQ2YQJhmkAuwnmZGTKBNA\/g88wAAKCRFRHgg\/P9eM4Ors7ONo62Dl8t6r8G\/yJiYuP+5c+rcEAAAOF0ftH+LC+zGoA7BoBt\/qIl7gRoXgugdfeLZrIPQLUAoOnaV\/Nw+H48PEWhkLnZ2eXk5NhKxEJbYcpXff5nwl\/AV\/1s+X48\/Pf14L7iJIEyXYFHBPjgwsz0TKUcz5IJhGLc5o9H\/LcL\/\/wd0yLESWK5WCoU41EScY5EmozzMqUiiUKSKcUl0v9k4t8s+wM+3zUAsGo+AXuRLahdYwP2SycQWHTA4vcAAPK7b8HUKAgDgGiD4c93\/+8\/\/UegJQCAZkmScQAAXkQkLlTKsz\/HCAAARKCBKrBBG\/TBGCzABhzBBdzBC\/xgNoRCJMTCQhBCCmSAHHJgKayCQiiGzbAdKmAv1EAdNMBRaIaTcA4uwlW4Dj1wD\/phCJ7BKLyBCQRByAgTYSHaiAFiilgjjggXmYX4IcFIBBKLJCDJiBRRIkuRNUgxUopUIFVIHfI9cgI5h1xGupE7yAAygvyGvEcxlIGyUT3UDLVDuag3GoRGogvQZHQxmo8WoJvQcrQaPYw2oefQq2gP2o8+Q8cwwOgYBzPEbDAuxsNCsTgsCZNjy7EirAyrxhqwVqwDu4n1Y8+xdwQSgUXACTYEd0IgYR5BSFhMWE7YSKggHCQ0EdoJNwkDhFHCJyKTqEu0JroR+cQYYjIxh1hILCPWEo8TLxB7iEPENyQSiUMyJ7mQAkmxpFTSEtJG0m5SI+ksqZs0SBojk8naZGuyBzmULCAryIXkneTD5DPkG+Qh8lsKnWJAcaT4U+IoUspqShnlEOU05QZlmDJBVaOaUt2ooVQRNY9aQq2htlKvUYeoEzR1mjnNgxZJS6WtopXTGmgXaPdpr+h0uhHdlR5Ol9BX0svpR+iX6AP0dwwNhhWDx4hnKBmbGAcYZxl3GK+YTKYZ04sZx1QwNzHrmOeZD5lvVVgqtip8FZHKCpVKlSaVGyovVKmqpqreqgtV81XLVI+pXlN9rkZVM1PjqQnUlqtVqp1Q61MbU2epO6iHqmeob1Q\/pH5Z\/YkGWcNMw09DpFGgsV\/jvMYgC2MZs3gsIWsNq4Z1gTXEJrHN2Xx2KruY\/R27iz2qqaE5QzNKM1ezUvOUZj8H45hx+Jx0TgnnKKeX836K3hTvKeIpG6Y0TLkxZVxrqpaXllirSKtRq0frvTau7aedpr1Fu1n7gQ5Bx0onXCdHZ4\/OBZ3nU9lT3acKpxZNPTr1ri6qa6UbobtEd79up+6Ynr5egJ5Mb6feeb3n+hx9L\/1U\/W36p\/VHDFgGswwkBtsMzhg8xTVxbzwdL8fb8VFDXcNAQ6VhlWGX4YSRudE8o9VGjUYPjGnGXOMk423GbcajJgYmISZLTepN7ppSTbmmKaY7TDtMx83MzaLN1pk1mz0x1zLnm+eb15vft2BaeFostqi2uGVJsuRaplnutrxuhVo5WaVYVVpds0atna0l1rutu6cRp7lOk06rntZnw7Dxtsm2qbcZsOXYBtuutm22fWFnYhdnt8Wuw+6TvZN9un2N\/T0HDYfZDqsdWh1+c7RyFDpWOt6azpzuP33F9JbpL2dYzxDP2DPjthPLKcRpnVOb00dnF2e5c4PziIuJS4LLLpc+Lpsbxt3IveRKdPVxXeF60vWdm7Obwu2o26\/uNu5p7ofcn8w0nymeWTNz0MPIQ+BR5dE\/C5+VMGvfrH5PQ0+BZ7XnIy9jL5FXrdewt6V3qvdh7xc+9j5yn+M+4zw33jLeWV\/MN8C3yLfLT8Nvnl+F30N\/I\/9k\/3r\/0QCngCUBZwOJgUGBWwL7+Hp8Ib+OPzrbZfay2e1BjKC5QRVBj4KtguXBrSFoyOyQrSH355jOkc5pDoVQfujW0Adh5mGLw34MJ4WHhVeGP45wiFga0TGXNXfR3ENz30T6RJZE3ptnMU85ry1KNSo+qi5qPNo3ujS6P8YuZlnM1VidWElsSxw5LiquNm5svt\/87fOH4p3iC+N7F5gvyF1weaHOwvSFpxapLhIsOpZATIhOOJTwQRAqqBaMJfITdyWOCnnCHcJnIi\/RNtGI2ENcKh5O8kgqTXqS7JG8NXkkxTOlLOW5hCepkLxMDUzdmzqeFpp2IG0yPTq9MYOSkZBxQqohTZO2Z+pn5mZ2y6xlhbL+xW6Lty8elQfJa7OQrAVZLQq2QqboVFoo1yoHsmdlV2a\/zYnKOZarnivN7cyzytuQN5zvn\/\/tEsIS4ZK2pYZLVy0dWOa9rGo5sjxxedsK4xUFK4ZWBqw8uIq2Km3VT6vtV5eufr0mek1rgV7ByoLBtQFr6wtVCuWFfevc1+1dT1gvWd+1YfqGnRs+FYmKrhTbF5cVf9go3HjlG4dvyr+Z3JS0qavEuWTPZtJm6ebeLZ5bDpaql+aXDm4N2dq0Dd9WtO319kXbL5fNKNu7g7ZDuaO\/PLi8ZafJzs07P1SkVPRU+lQ27tLdtWHX+G7R7ht7vPY07NXbW7z3\/T7JvttVAVVN1WbVZftJ+7P3P66Jqun4lvttXa1ObXHtxwPSA\/0HIw6217nU1R3SPVRSj9Yr60cOxx++\/p3vdy0NNg1VjZzG4iNwRHnk6fcJ3\/ceDTradox7rOEH0x92HWcdL2pCmvKaRptTmvtbYlu6T8w+0dbq3nr8R9sfD5w0PFl5SvNUyWna6YLTk2fyz4ydlZ19fi753GDborZ752PO32oPb++6EHTh0kX\/i+c7vDvOXPK4dPKy2+UTV7hXmq86X23qdOo8\/pPTT8e7nLuarrlca7nuer21e2b36RueN87d9L158Rb\/1tWeOT3dvfN6b\/fF9\/XfFt1+cif9zsu72Xcn7q28T7xf9EDtQdlD3YfVP1v+3Njv3H9qwHeg89HcR\/cGhYPP\/pH1jw9DBY+Zj8uGDYbrnjg+OTniP3L96fynQ89kzyaeF\/6i\/suuFxYvfvjV69fO0ZjRoZfyl5O\/bXyl\/erA6xmv28bCxh6+yXgzMV70VvvtwXfcdx3vo98PT+R8IH8o\/2j5sfVT0Kf7kxmTk\/8EA5jz\/GMzLdsAAAAgY0hSTQAAeiUAAICDAAD5\/wAAgOkAAHUwAADqYAAAOpgAABdvkl\/FRgAADcFJREFUeNrsmnmQXNV1xn\/3Lf1eb9OzdM+qGe2DFgZFIGQIizFGBpRAgQUhmDUOqQI7qYIirtguAgHbyBUbO3FsEpcTIixMICKgsDgskYyNWGwEaLEQoA1mn+np6Z6ZXt9288d9o8E2IhKSUymXXtWrN931+vX97vnOOd93eoSUkt+FQ+N35DgO5DiQ39JhfNCbQojfeC+ia0RtC8\/zKdUclvUspVQus3hJD\/nxMfoGhwkqU3zi\/NV2NF7X+OSjD2WSDem6IJAWgKGJ2kR+fPLiNX+UrZaL45ue+XHViCbo7GijpaWVHdu3kYhH2frGTmzTQAiB5\/u4fvAba\/mgAmUczS4IIfA9j+pUIbpo4bwerLozS1b6FLtjwfJP\/sU3WnNTtVix7JgEAUnLcNPJSAlqw6X+\/W\/0nHrGa8ItbRkZHNjpNjVVP2jzjjoih3VIKE5MGF2zu1bH5yy9WrZ0n5N1zMzOgTFGXxrAK1XA80FK8APwPAuBZdrRxpbGhiWL5i6+qi0psk0L9m1u0ksP\/PzFF5+ORdu8j7ypHxSmD6eWR6nmsmJZz6KTV11y+z6v8Q\/2lURd\/0gOr1gEASBACAUiEBAEClQQQAB4EnyJmUgxb14ny+emJhdEhp7a9Oj6r7z82vbdlqGjadoRUeuIgFimQaXqcO6qVZfPP++P7970zviCvXv2EggDYgkQEiRhFMK\/gzAivgShhfVFqKsPeGDE6jj1lKV8+pTY3lf+\/e9v+4+NTz1sGTpSSpxjDUQHIgL90muuvTl65pV3\/dvz22Pl0QHwqmqBdh1omtp1yftASBUFCUgdhD4DBB00AzQbtCQdJ53IFy9bUHln\/V\/f\/t17f\/BtobbgsIAcdvnVBNql11x7q7HqhrXrt\/bFyq4Ltg1GBHwPnKpa7K9uSUgzDTQLTAuMXzvNOMQbobmTgckodzyvRRfe9J27P3\/TDV8QR7K+w71x1YWrr01ccMOdD768z3Q8D+oaIJoEwwRdA68CgaeiIlA5IoR6rZkKsG6BFlGgtBBErAHqZ0FmNjS3MZ6rcMcjA+aCq+6647I1l15\/TIEsnNu1fPEVf\/61B7b2216tBpapAMTqwIqCpgMBuI56pBAc5JcIgei2AqJH1GnGQhDt0NQJdRnFX1Ekv38\/X3\/kHfvsz962dkn33BXHBIita6k1N976lScOVNvL+TxYEbU4ISBiQaIhBKNB4IAMFO\/F+2hlRn6VVmZ0BkS6E1Jp0CRUJ6A4BrLE8N5e1m+tNt\/wl3d+LaJRd9RAzr\/o4iv3pntW7enPqcV6rtps3QijkoREWi2QAHxXRUDTFRjdACMKhq0iEYlCvAEa2iHTCXXNoAmoFmBqFKbyUKtCRPCL7ft5W19yzqcvv\/yqowLSEDXTs89aff2W\/ZMRKXTQTdUXPE+BMUy104l6RQ3DVGCmaRcJIxCJQTSuSnS8HhrboLkTUs1qBZVxmByFYgGcmqp8AgLf55lt2Uj32Zdc15CwMkcMZLr4nnb2OasGY3NOGslOQuCD1ELa6ApMEIBpQiwO9RlIpsE01FlzYXAA+nphYBgGRqEqoKkDWmere5FQzYcg8uBUQPozC9AE\/UN5ekVHz2lnnPVJAP0QUsY4hPpAB635hGXn7iiaUemEVPJDBaELRR3fn8kBTVfn2ADs3UU608Q5n+gJfq+7q2hEkuweLie39DliXxHIpBSdSuMwOQKlvIoE8mDFRqrK51Wr7B4OYiuWnf4p45n\/3uBJ6R+R1upsb+5KdC1ZPjRUUHmhh7yXngLkS1V28VUuWLb68vwEl328x7vzxst3z25t3O041UKlUsZz\/fqi0Jf+8w5v0Xef7dXdhAVuXtHJdZQqQMxEIwjRiIDBbJFgVueSlkx9+0C20HdEQKxEalb\/hN+RHehXOy+tsGfoICKqZ7ieAumbIAX09XLN6tO9H9y8ZrOpadt937ftaMw2IlHGstmRYGL8vS+ubBwW1eCcbz28UyedVJ9HqggRyhv5vqjogqHcBOX5mXnp1vZ5hwKiHQpdqr5pbtUVLf5oPxRzMDEGk+NQmoRqRckOEYHAAC+AwX46jTJ3XX3udsvQt2u6niyVy9ozzz777qZNmw7ohqEnG9PJ4aHc63+2IrVzaaMLY7kwp3QwNBVhXczQiwC0AK84RWDVZ1pa2+dHxBHI+PbWNM2tbe0emqBcBGmDqIKhQyXs0tN9wTRVjozkuOSiE91ZDfFfOq5re57v33LLLU+88MILL0spWbly5elr1679w3hdg21r3q4LTuk4cdejbxs0N4AIVbEfyn4pFX0DBwIXfJeJsosVT2Yy6frDr1rxRBzTsut8N1C77fvqwbUa1EpQmlDRKYxCIQfj41Aq0t3ZUiqWSmXTjMQefvjhnevWrXs+lUpN1tXVTT700EPPb968eXdbW2scoU0snF0\/RSwOEQNMoapV4IDngF8BWQXpKpCapOh4eGh2Ll84fCD7DvQKTdc06fvKR\/jB+67Tpw+uD46jzkBD001ZLleo1WpaLpcrtbe312zbJpFI0N3d7dRqtXIsFtNsOyo14fqYDkQkmBI0XxUS6QAuCB90qShnGkhdBylFzUMcNrUcX0rfccqGJpTkkHJGemtGqJ1CEWjaYCchoTFWFvHAd+yR0dHKeeedd1JbW9uSe++9902AtWvXLlq2bNlix3EqqWQyvufA1iQTg+CmVNWLWWCb4QZ5SiH4QWjGfBJxG6EJT36Axv7QqpUdHc4m53gqH9BVH9EjKi+08KqHeWInIGPz3N5y5PpPRU7Ij2RfyLS2NS6PRP5kzZo1L5umycqVK0+fNWtWKvC93JSr9Tz3zphFRwvogXKMEUt9l9BnzJgbVsaKT6o+xlilWDhiz54bG+1tCGp5YnUNyECp14NSPIzK9NWwYXYLL40GbHyPkz8zp360f3jorVRjuu6mz33uoqhtS8dxKp7r5QzT6P76gz9esW2kBMuWQtVRKsBH5YOuK2GqaYoJToDWbBExKpPZ4cHeI9ZaTnmqvz1lDqcbGkGG0RBm6BX1UAFbilbJDDTPIuhcxB0bJuwf7qhd0JhuPNOUTiQ3MlgcHx0q6tI1y7XaGV\/6\/mMX3rPuKZtUQjWKmAmJKMQjilo6qslqEiwDYhFaZ6exykO92YH+A0cckYGBwV53vO\/t1ubuxWO5ogq5mAagK2MUTUB9M6RnQTQFEgo5nb\/63jZ7Q2dwxkUrO09ePDc9JUSZ7W\/9PLlhy87ortGqoHOhyoH8BNQnFQBfU0VEhtJfovIDQUeTRXTXuwdGsvm+IwZS8ynk3nvzxRNWrLz4l\/uyGlKbAWPYEK1TIJo6lCdxfZgcA6+Al4rxyr4R8crubTFMPQZVqGYhakDnQtX0KhOQL4Q6TVUmNA1cpXzRNZAawogwP1IJ9r7005\/VoPCRZPxrL2\/ZPD9e3d+STs8oXyOqLG6qBdIdSsK7nuopuUHIj4BbhXQjzOmCznaY1QlzFkBjE1QKKieEptTuVBEcX\/UqXSg6aeHgQkpaMnHmTR048PqLWzZ\/ZD8ykM3vGN31kyc\/fupcVal0G2IpaGiFTDskGxQd8iOQG4CJUaiVlX5ya0oMTjdTNyynTlndE4T0qVSgWFHPCQK1Iss46P1PazYZfOaxJ\/vzk9uPxiF6Gzc8eP\/HMvnd3Yvngx6HhhbIdCiX53gKxNgAFLJQKYemy1eJ7PsKgOMoCaJHVJXzQ60WhHlQqkDFC1\/Lg1ZhTlcjHxt\/8+3HfvTAOlUBjsLqFqbKuzd876v33Hh+V7W+eyEkmpX78zzIj4aRGINqWe289FUTDRuZUsdeOFExwl4B+E44hfTU\/aUK1EJL4AVEklGuaqe28W\/vvGeiWtt9LKYozitbt23c+8R37rvtmh6sTBNM1WAiC+NDSmvVyqoKSVfJjMBXC\/RcpZ2kFyqD0AIYlhoxShlqudDflGpQdiBicV1PM333ffNffvHG9scA51gAkUDuX++779vu0\/c8\/uUL01jOJAz0qSpVK4W764bRCDVT4M6o1yCcFwotVAiWUtL4KipuTUWl4iEcwRXL2ok+\/v3HHvnRA9+SMMYhZMlHGtBVXH\/v3bf\/zZfEk199\/NbzEtiiCoUC+LUQxPTi3VAnTQPxQqc3PXHUFb0MWzU9gSoCpRJmNMpnlreTefIf\/3PdPd\/4ctn19x3zafxB56iLhdf96Q1f6Dr3s9fev3nQ2rOnN1SqMxPSg5NGjbBHmBCJKAOl6+Ec21dj1kACJm1dHVxxctrJPvVP6x754f3frAVyzyEpcjRD7F8bsrSevvKUSy+6\/ubP7yy1LX7u1XdFLptH+o7a5Wm3p2nKHkdCA2boytKGQIUOdQmbMxa00+Pvf+sn6\/\/uH159bdtGCUMfRqdjBWQaTCwZs5atueLKqzM9564+UE51vjNQ1AayExSKJXw3rJZ6CMSyIGqjxywa6uK0ZOLMr9OCzlp\/X\/61p\/\/rqUceWj9RcbYD5f8tJ44lkPcfdS2NqeW\/f9bZq1KzFp0aa1t0QlHEmkfKwnb1mAg0E2maGKaGqbmyJSarca+QLR3Y8XZh385XX\/nZT58dKUy+Dkwd9o9lvyUgB38LMgWts7s6FiTqG+fokVhbfWM6bVh2DCEInGo5n8uO+dXS0FQ+9957fUN7XBg+nNL6fw3k16lnAaErI9TmOEDtcMrpMQFy\/B8GjgM5DuQ4kP+3x\/8MAHWpUzAU7qJ7AAAAAElFTkSuQmCC' alt='img'\/><\/div><div class='stb-caption-content'> <\/div><div class='stb-tool'><\/div><\/div><div class='stb-content'><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>if(\n  is_selected(),\n  \"plage\"  || '\\n'  ||  \n  'Total d\u00e9chets : ' || \n  aggregate(\n    'suivi_plages_dechets',\n    'sum',\n    \"quantite\",\n    filter:= \"plage\" = attribute(@parent, 'plage')\n  ),\n  ''\n)\n<\/code><\/pre>\n\n\n\n<p><\/div><\/div>\n\n\n\n<p>This expression checks whether the range is selected (is_selected()), then displays :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Its name<\/li>\n\n\n\n<li>The sum of waste for this range, calculated dynamically via aggregate().<\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Result\"><\/span>Result<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n\n<p>When you select one or more ranges, the label is displayed only on those selected, with their respective waste totals.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Variant_optional\"><\/span>Variant (optional)<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>You can also filter via the attribute table or a search form, and the labels will react automatically to the selection.<\/p>\n\n\n\n<figure class=\"wp-block-video aligncenter\"><video height=\"992\" style=\"aspect-ratio: 1674 \/ 992;\" width=\"1674\" controls src=\"https:\/\/www.sigterritoires.fr\/wp-content\/uploads\/2025\/06\/20250617_144155.mp4\"><\/video><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Step_4_Organize_the_workspace\"><\/span>Step 4: Organize the workspace<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>Create a dashboard interface:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Left: attribute table or filters<\/li>\n\n\n\n<li>Center: map<\/li>\n\n\n\n<li>Bottom: Data Plotly graph<\/li>\n\n\n\n<li>Right: counters\/statistics (via text frames)<\/li>\n<\/ul>\n\n\n\n<p>Save your layout via Project &gt; Save layout.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"In_a_nutshell\"><\/span>In a nutshell<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>Element Tools used Filtering Attribute table \/ Form Reactive graphics Data Plotly Dynamic statistics Expressions \/ Custom widgets User interface Workspace organization<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Element <\/th><th>Tools used<\/th><\/tr><\/thead><tbody><tr><td>Filtering <\/td><td>Attribute table \/ Form<\/td><\/tr><tr><td>Reactive graphics<\/td><td>Data Plotly<\/td><\/tr><tr><td>Dynamic statistics <\/td><td>Expressions \/ Custom widgets<\/td><\/tr><tr><td>User interface<\/td><td>Workspace organization<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Bonus_advanced_tips\"><\/span>Bonus: advanced tips<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Create a virtual layer with a dynamic filter to centralize displayed data<\/li>\n\n\n\n<li>Use CASE and regexp_match() functions for advanced groupings<\/li>\n\n\n\n<li>Test plug-ins: Quick Filter, Attribute Table Filter, Input Widgets<\/li>\n\n\n\n<li>Consider a <a href=\"https:\/\/www.sigterritoires.fr\/index.php\/en\/starting-with-postgres-postgis\/\">PostgreSQL\/PostGIS<\/a> project with materialized views filterable by date or site<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"To_be_continued%E2%80%A6\"><\/span>To be continued\u2026<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>In a future article, we&rsquo;ll look at how to transform this QGIS dashboard into a web interface with :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Export to QGIS Server or Lizmap<\/li>\n\n\n\n<li>Filterable online dashboard (range, date\u2026)<\/li>\n\n\n\n<li>Integration into a participatory or citizen website<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n","protected":false},"excerpt":{"rendered":"<p>Objective Create a dynamic monitoring interface in QGIS with : All without leaving the QGIS interface! Use case: monitoring beach litter Let&rsquo;s take our releves_dechets layer with : Field Description beach Name of beach type_waste Waste&hellip;<\/p>\n","protected":false},"author":1,"featured_media":14304,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"give_campaign_id":0,"_bbp_topic_count":0,"_bbp_reply_count":0,"_bbp_total_topic_count":0,"_bbp_total_reply_count":0,"_bbp_voice_count":0,"_bbp_anonymous_reply_count":0,"_bbp_topic_count_hidden":0,"_bbp_reply_count_hidden":0,"_bbp_forum_subforum_count":0,"sfsi_plus_gutenberg_text_before_share":"","sfsi_plus_gutenberg_show_text_before_share":"","sfsi_plus_gutenberg_icon_type":"","sfsi_plus_gutenberg_icon_alignemt":"","sfsi_plus_gutenburg_max_per_row":"","_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[3394,1377],"tags":[3504,3468,3502,1758,1386],"class_list":["post-14527","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-pluigin-en","category-qgis-en","tag-dashboard","tag-data-plotly-en","tag-dynamic-labels","tag-plugin-en","tag-qgis-en"],"aioseo_notices":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/www.sigterritoires.fr\/wp-content\/uploads\/2025\/06\/tableau_de_bord.jpg?fit=1278%2C812&ssl=1","jetpack_shortlink":"https:\/\/wp.me\/p6XU0A-3Mj","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.sigterritoires.fr\/index.php\/wp-json\/wp\/v2\/posts\/14527","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.sigterritoires.fr\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.sigterritoires.fr\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.sigterritoires.fr\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.sigterritoires.fr\/index.php\/wp-json\/wp\/v2\/comments?post=14527"}],"version-history":[{"count":0,"href":"https:\/\/www.sigterritoires.fr\/index.php\/wp-json\/wp\/v2\/posts\/14527\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.sigterritoires.fr\/index.php\/wp-json\/wp\/v2\/media\/14304"}],"wp:attachment":[{"href":"https:\/\/www.sigterritoires.fr\/index.php\/wp-json\/wp\/v2\/media?parent=14527"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.sigterritoires.fr\/index.php\/wp-json\/wp\/v2\/categories?post=14527"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.sigterritoires.fr\/index.php\/wp-json\/wp\/v2\/tags?post=14527"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}