DataPlotly icon indicating copy to clipboard operation
DataPlotly copied to clipboard

Python error "'NoneType' object does not support item assignment" in create_layout L101

Open Gustry opened this issue 8 months ago • 4 comments

Describe the bug When I open a layout, I have several time this Python error showing up :

        # add font size parameter from the title setting
        title = settings.data_defined_title if settings.data_defined_title else settings.layout['title']
        if isinstance(title, str):
            title = {"text": title}
        title["font"] = {
            "size": settings.layout.get('font_title_size', 10),
            "color": settings.layout.get('font_title_color', "#000"),
            "family": settings.layout.get('font_title_family', "Arial"),
        }

From Python First AID plugin

{
  "ExceptionDetails": {
    "Type": "TypeError",
    "Message": "'NoneType' object does not support item assignment"
  },
  "Environment": {
    "Qgis Version": "3.40.5-Bratislava",
    "Operating System": "linux",
    "Locale": "en"
  },
  "Trace": [
    {
      "Name": "draw",
      "Filename": "plot_layout_item.py",
      "LineNo": 157,
      "Variables": {
        "self": "<DataPlotly.layouts.plot_layout_item.PlotLayoutItem object at 0x714ef3fdbe30>",
        "context": "<qgis._core.QgsLayoutItemRenderContext object at 0x714ef3fdab10>"
      }
    },
    {
      "Name": "load_content",
      "Filename": "plot_layout_item.py",
      "LineNo": 223,
      "Variables": {
        "self": "<DataPlotly.layouts.plot_layout_item.PlotLayoutItem object at 0x714ef3fdbe30>",
        "base_url": "PyQt5.QtCore.QUrl('file:///tmp/tmpygrqthq_/3bamaryl_stat.qgs')"
      }
    },
    {
      "Name": "create_plot",
      "Filename": "plot_layout_item.py",
      "LineNo": 194,
      "Variables": {
        "self": "<DataPlotly.layouts.plot_layout_item.PlotLayoutItem object at 0x714ef3fdbe30>",
        "polygon_filter": "None",
        "visible_features_only": "False",
        "config": "{'displayModeBar': False, 'staticPlot': True}",
        "plot_factory": "<DataPlotly.core.plot_factory.PlotFactory object at 0x714ef3fda960>",
        "pl": "[Bar({\n    'customdata': [date_releve],\n    'ids': [],\n    'marker': {'color': '#33a02c',\n               'colorbar': {'len': 0.8},\n               'colorscale': [[0.0, 'rgb(255,255,255)'], [0.125,\n                              'rgb(240,240,240)'], [0.25, 'rgb(217,217,217)'],\n                              [0.375, 'rgb(189,189,189)'], [0.5,\n                              'rgb(150,150,150)'], [0.625, 'rgb(115,115,115)'],\n                              [0.75, 'rgb(82,82,82)'], [0.875, 'rgb(37,37,37)'],\n                              [1.0, 'rgb(0,0,0)']],\n               'line': {'color': '#33a02c', 'width': 1.0},\n               'reversescale': False,\n               'showscale': False},\n    'name': 'densite',\n    'opacity': 1.0,\n    'orientation': 'v',\n    'text': [],\n    'textposition': 'auto',\n    'x': [],\n    'y': []\n}), Scatter({\n    'customdata': [date_releve],\n    'ids': [],\n    'line': {'dash': 'solid', 'width': 3.0},\n    'marker': {'color': '#000000',\n               'colorbar': {'len': 0.8},\n               'line': {'color': '#000000', 'width': 3.0},\n               'reversescale': False,\n               'showscale': False,\n               'size': 10.0,\n               'symbol': 0},\n    'mode': 'markers',\n    'opacity': 0.6,\n    'text': [],\n    'textposition': 'top center',\n    'x': [],\n    'y': []\n})]",
        "current": "2",
        "plot_setting": "<DataPlotly.core.plot_settings.PlotSettings object at 0x714ef351d010>",
        "factory": "<DataPlotly.core.plot_factory.PlotFactory object at 0x714ef3fda4e0>"
      }
    },
    {
      "Name": "__init__",
      "Filename": "plot_factory.py",
      "LineNo": 117,
      "Variables": {
        "self": "<DataPlotly.core.plot_factory.PlotFactory object at 0x714f08005490>",
        "settings": "<DataPlotly.core.plot_settings.PlotSettings object at 0x714ef351d010>",
        "context_generator": "<DataPlotly.layouts.plot_layout_item.PlotLayoutItem object at 0x714ef3fdbe30>",
        "visible_region": "None",
        "polygon_filter": "None",
        "__class__": "<class 'DataPlotly.core.plot_factory.PlotFactory'>"
      }
    },
    {
      "Name": "rebuild",
      "Filename": "plot_factory.py",
      "LineNo": 446,
      "Variables": {
        "self": "<DataPlotly.core.plot_factory.PlotFactory object at 0x714f08005490>"
      }
    },
    {
      "Name": "_build_layout",
      "Filename": "plot_factory.py",
      "LineNo": 476,
      "Variables": {
        "self": "<DataPlotly.core.plot_factory.PlotFactory object at 0x714f08005490>"
      }
    },
    {
      "Name": "create_layout",
      "Filename": "scatter.py",
      "LineNo": 70,
      "Variables": {
        "settings": "<DataPlotly.core.plot_settings.PlotSettings object at 0x714ef3f0b7a0>",
        "__class__": "<class 'DataPlotly.core.plot_types.scatter.ScatterPlotFactory'>"
      }
    },
    {
      "Name": "create_layout",
      "Filename": "plot_type.py",
      "LineNo": 101,
      "Variables": {
        "settings": "<DataPlotly.core.plot_settings.PlotSettings object at 0x714ef3f0b7a0>",
        "y_title": "None",
        "x_title": "None",
        "range_x": "None",
        "range_y": "None",
        "bg_color": "rgba(0,0,0,0)",
        "title": "None"
      }
    }
  ]
}

To Reproduce Steps to reproduce the behavior:

  1. Open a project (given by another user, not mine).
  2. Open a specific layout
  3. See this Python error many times

Screenshots If applicable, add screenshots to help explain your problem.

Desktop (please complete the following information):

  • OS: [e.g. iOS] Ubuntu 24.04
  • QGIS release [e.g. QGIS 3.10] 3.40
  • DataPlotly release [e.g. 3.0] : 4.2.0 (from latest commit)

Additional context Add any other context about the problem here.

Gustry avatar Apr 10 '25 15:04 Gustry

Got something similar since I upgrade from 3.34.0 LTR to 3.40.6 LTR Seems it have something to do with fonts for title

Doing this in plot_type.py "solved" the problem (lines 101 to 106)

    _"""title["font"] = {
        "size": settings.layout.get('font_title_size', 10),
        "color": settings.layout.get('font_title_color', "#000"),
        "family": settings.layout.get('font_title_family', "Arial"),
    }"""_

Error before edit was :

TypeError: 'NoneType' object does not support item assignment Traceback (most recent call last): File "C:\Users/XXX/AppData/Roaming/QGIS/QGIS3\profiles\default/python/plugins\DataPlotly\layouts\plot_layout_item.py", line 157, in draw self.load_content() File "C:\Users/XXX/AppData/Roaming/QGIS/QGIS3\profiles\default/python/plugins\DataPlotly\layouts\plot_layout_item.py", line 223, in load_content self.web_page.mainFrame().setHtml(self.create_plot(), base_url) ^^^^^^^^^^^^^^^^^^ File "C:\Users/pos/AppData/Roaming/QGIS/QGIS3\profiles\default/python/plugins\DataPlotly\layouts\plot_layout_item.py", line 194, in create_plot factory = PlotFactory(plot_setting, self, polygon_filter=polygon_filter) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users/XXX/AppData/Roaming/QGIS/QGIS3\profiles\default/python/plugins\DataPlotly\core\plot_factory.py", line 117, in init self.rebuild() File "C:\Users/XXX/AppData/Roaming/QGIS/QGIS3\profiles\default/python/plugins\DataPlotly\core\plot_factory.py", line 446, in rebuild self.layout = self._build_layout() ^^^^^^^^^^^^^^^^^^^^ File "C:\Users/XXX/AppData/Roaming/QGIS/QGIS3\profiles\default/python/plugins\DataPlotly\core\plot_factory.py", line 476, in _build_layout return PlotFactory.PLOT_TYPES[self.settings.plot_type].create_layout(self.settings) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users/XXX/AppData/Roaming/QGIS/QGIS3\profiles\default/python/plugins\DataPlotly\core\plot_types\bar_plot.py", line 79, in create_layout layout = super(BarPlotFactory, BarPlotFactory).create_layout(settings) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users/XXX/AppData/Roaming/QGIS/QGIS3\profiles\default/python/plugins\DataPlotly\core\plot_types\plot_type.py", line 101, in create_layout title["font"] = { ~~~~~^^^^^^^^ TypeError: 'NoneType' object does not support item assignment

Version de Python : 3.12.10 (main, Apr 9 2025, 08:14:47) [MSC v.1943 64 bit (AMD64)] Version de QGIS : 3.40.6-Bratislava Bratislava, 5d7f6a3e26

palight avatar May 20 '25 14:05 palight

@Gustry I cannot reproduce the issue, even if I tried to create a project with a layout and a plot. Saved the project, closed QGIS, reopened QGIS, removed the layer used in the layout plot. Saved again, closed again and finally reopened the layout.

Not sure, but what is your and also @palight plotly version installed? Could it be related to https://github.com/ghtmtt/DataPlotly/pull/373?

ghtmtt avatar May 28 '25 14:05 ghtmtt

The issue would rather come from the line https://github.com/ghtmtt/DataPlotly/blob/master/DataPlotly/core/plot_types/plot_type.py#L98:

title = settings.data_defined_title if settings.data_defined_title else settings.layout['title']

The settings.layout['title'] is None.

rldhont avatar Jun 11 '25 15:06 rldhont

Can confirm that this bug occurs when the Plot element has no title or when the Plot title under Layout Options is left blank.

In that case, when the layout is loaded, the Plot is not automatically generated and the error is thrown.

To reproduce:

  1. Create a layout and add a Plot.
  2. Remove the Plot title and leave the Plot title under Layout Options blank.
  3. Save the layout/project.
  4. Restart QGIS.
  5. Open the project created in 1.
  6. The created plot will not be automatically generated and the error will be thrown.

A simple workaround would be to add a Plot title then click Update Plot but the error will reoccur next time you open the layout as long as the plot has no title.

I agree with @rldhont above that this is related to line 98. Maybe add a condition that checks if settings.layout['title'] is None and return a blank string ("") if it isn't, else return the string as is? Or raise an exception informing the user that the Plot title is blank/None?

This rather crude implemetation worked for me:

title = settings.data_defined_title if settings.data_defined_title else (settings.layout['title'] or '')

benhur07b avatar Sep 11 '25 01:09 benhur07b