diff --git a/src/gisaf/api/dashboard.py b/src/gisaf/api/dashboard.py
index 2050287..bb6b2b7 100644
--- a/src/gisaf/api/dashboard.py
+++ b/src/gisaf/api/dashboard.py
@@ -1,7 +1,5 @@
 import logging
 from pathlib import Path
-from json import dumps
-from typing import Annotated
 
 from fastapi import Depends, APIRouter, HTTPException, status, responses
 from sqlalchemy.orm import selectinload
@@ -10,7 +8,7 @@ import pandas as pd
 import geopandas as gpd
 
 from gisaf.config import conf
-from gisaf.utils import NumpyEncoder
+from gisaf.utils import dict_array_to_list
 from gisaf.database import fastapi_db_session as db_session
 from gisaf.models.authentication import User
 from gisaf.models.dashboard import (
@@ -138,16 +136,8 @@ async def get_dashboard_page(group: str, name: str,
                        'see debug message')
         logger.exception(err)
     if page.plot:
-        try:
-            plot = page.get_plot()
-            plotData = {
-                'data': [d.to_plotly_json() for d in plot.data],
-                'layout': plot.layout.to_plotly_json(),
-            }
-        except Exception as err:
-            logger.warning(f'Dashboard: cannot add plot for page {page.name}, '
-                           'see debug message')
-            logger.exception(err)
-        else:
-            dp.plotData = dumps(plotData, cls=NumpyEncoder)
+        plot = page.get_plot()
+        ## Convert manually numpy arrays to lists
+        dp.plotData = [dict_array_to_list(d.to_plotly_json()) for d in plot.data]
+        dp.plotLayout = plot.layout.to_plotly_json()
     return dp
\ No newline at end of file
diff --git a/src/gisaf/models/dashboard.py b/src/gisaf/models/dashboard.py
index 76c2068..5a3f350 100644
--- a/src/gisaf/models/dashboard.py
+++ b/src/gisaf/models/dashboard.py
@@ -3,9 +3,11 @@ from pickle import loads
 from pathlib import Path
 from datetime import datetime
 import logging
+from typing import Any
 # from typing import Any
 
 from matplotlib.figure import Figure
+from plotly.graph_objs._figure import Figure as PlotlyFigure
 from sqlmodel import Field, Relationship, String, JSON
 from pydantic import BaseModel
 import pandas as pd
@@ -110,18 +112,22 @@ class DashboardPageCommon:
                     #f'in {self.get_attachment_file_name()}')
         return self.attachment
 
-    def get_page_df(self):
+    def get_page_df(self) -> pd.DataFrame | None:
         """
         Get the dataframe of the page
         """
         if not self.df:
-            return
+            return None
         try:
-            return pd.read_pickle(BytesIO(self.df), compression=None)
+            df = pd.read_pickle(BytesIO(self.df), compression=None)
         except KeyError:
             raise NotADataframeError()
+        if isinstance(df, dict):
+            return None
+        else:
+            return df
 
-    def get_plot(self):
+    def get_plot(self) -> PlotlyFigure | None:
         if self.plot is not None:
             return loads(self.plot)
 
@@ -293,7 +299,8 @@ class Dashboard(BaseModel):
     html: str | None = None
     attachment: str | None = None
     dfData: list = []
-    plotData: str | None = None
+    plotData: list[dict] | None = None
+    plotLayout: dict[str, Any] | None = None
     notebook: str | None = None
     expandedPanes: list[str] | None = None
     sections: list[DashboardSection] | None = None
diff --git a/src/gisaf/utils.py b/src/gisaf/utils.py
index 0894374..3273e83 100644
--- a/src/gisaf/utils.py
+++ b/src/gisaf/utils.py
@@ -83,6 +83,17 @@ gisTypeSymbolMap = {
 # ).transform
 
 
+def dict_array_to_list(d: dict) -> dict:
+    '''Convert any ndarray a dict to plain python list.
+    Useful for transforming a Dataframe to a serializable object'''
+    for k, v in d.items():
+        if isinstance(v, dict):
+            dict_array_to_list(v)
+        else:
+            if isinstance(v, ndarray):
+                d[k] = v.tolist()
+    return d
+
 class NumpyEncoder(JSONEncoder):
     """
     Encoder that can serialize numpy arrays and datetime objects