mlflow/mlflow · error · TypeError
Unsupported figure object type: '{type(figure)}'
Error message
Unsupported figure object type: '{type(figure)}' What it means
log_figure() only accepts matplotlib figure objects and Plotly figure objects; anything else (including plain dicts, bokeh figures, or nested figures) raises this TypeError. The library cannot serialize an unknown figure type to an artifact file.
Source
Thrown at mlflow/tracking/client.py:3098
# `is_matplotlib_figure` is executed only when `matplotlib` is found in `sys.modules`.
# This allows logging a `plotly` figure in an environment where `matplotlib` is not
# installed.
if "matplotlib" in sys.modules and _is_matplotlib_figure(figure):
figure.savefig(tmp_path, **save_kwargs)
elif "plotly" in sys.modules and _is_plotly_figure(figure):
file_extension = os.path.splitext(artifact_file)[1]
if file_extension == ".html":
save_kwargs.setdefault("include_plotlyjs", "cdn")
save_kwargs.setdefault("auto_open", False)
figure.write_html(tmp_path, **save_kwargs)
elif file_extension in [".png", ".jpeg", ".webp", ".svg", ".pdf"]:
figure.write_image(tmp_path, **save_kwargs)
else:
raise TypeError(
f"Unsupported file extension for plotly figure: '{file_extension}'"
)
else:
raise TypeError(f"Unsupported figure object type: '{type(figure)}'")
def log_image(
self,
run_id: str,
image: Union["numpy.ndarray", "PIL.Image.Image", "mlflow.Image"],
artifact_file: str | None = None,
key: str | None = None,
step: int | None = None,
timestamp: int | None = None,
synchronous: bool | None = None,
) -> None:
"""
Logs an image in MLflow, supporting two use cases:
1. Time-stepped image logging:
Ideal for tracking changes or progressions through iterative processes (e.g.,
during model training phases).
View on GitHub (pinned to 6a27f2decc)
Solutions
- Convert to a supported type: for plotly use plotly.graph_objects.Figure; for matplotlib use matplotlib.figure.Figure (e.g., call .figure on a seaborn axis, or plt.gcf()).
- For PIL images or numpy arrays, use client.log_image() instead of log_figure().
- For unsupported libraries (bokeh, altair), export to HTML/PNG bytes yourself and log the file via log_artifact().
Example fix
// before client.log_figure(run_id, ax, "plot.png") # seaborn axes object // after client.log_figure(run_id, ax.figure, "plot.png")
Defensive patterns
Strategy: type-guard
Validate before calling
import matplotlib.figure
from plotly.graph_objs import Figure
if not isinstance(figure, (matplotlib.figure.Figure, Figure)):
raise TypeError(f"log_figure accepts matplotlib/plotly figures, got {type(figure)}")
client.log_figure(run_id, figure, artifact_file) Type guard
def is_loggable_figure(fig) -> bool:
import matplotlib.figure
from plotly.graph_objs import Figure
return isinstance(fig, (matplotlib.figure.Figure, Figure)) Try / catch
try:
client.log_figure(run_id, figure, artifact_file)
except TypeError as e:
if "Unsupported figure object type" in str(e):
client.log_artifact(run_id, export_figure_to_file(figure), artifact_file)
else:
raise Prevention
- Use log_image() for PIL images / numpy arrays, not log_figure().
- For seaborn axis-level results, log ax.figure rather than ax.
- Standardize on matplotlib Figure or plotly Figure objects before logging.
- Validate figure type in your plotting helper before returning it for logging.
When it happens
Trigger: client.log_figure(run_id, some_non_figure_object, "fig.png") where the object is not a matplotlib.figure.Figure or plotly figure (e.g., a seaborn axis-level object passed without .fig access, a bokeh figure, or a PIL image mistakenly routed to log_figure).
Common situations: Passing a PIL image or numpy array — those belong in log_image(); passing seaborn plots (some return axes, not figures); version changes where a custom plot library figure was expected to be supported but isn't.
Related errors
- Unsupported file extension for plotly figure: '{file_extensi
- Unsupported data type.
- INVALID_PARAMETER_VALUE
- adapter_type must be a string, got {type(adapter_type).__nam
- 'prompt' value must be a string or list of strings, got {typ
AI-assisted analysis of mlflow/mlflow@6a27f2decc (2026-08-29).
Data as JSON: /api/errors/70f197cbb06d2af1.
Report an issue: GitHub.