Skip to content

[Bug]: installing topostats with python 3.10 installs deprecated matplotlib code #1189

@tobyallwood

Description

@tobyallwood

Checklist

  • Find the offending file in the output. If processing halts, re-run analysis with topostats --core 1 process.
  • Describe the bug.
  • Include the configuration file.
  • Copy of the log-file from running with topostats --log-level debug <command>.
  • The exact command that failed. This is what you typed at the command line, including any options.
  • TopoStats version, this is reported by topostats --version
  • Operating System and Python Version

Describe the bug

Installing the topostats library with python 3.10 installs matplotlib 3.9.4, which contains a function using deprecated values : 'site-packages\topostats\plottingfuncs.py' -> save_figure().

When running topostats process in tests/resources/ with this default setup, the process fails with the message:

DeprecationWarning: 'mode' parameter is deprecated and will be removed in Pillow 13 (2026-10-15)

Solution:
Switch to python version 3.11.0, and then upgrade matplotlib (pip install --upgrade matplotlib) so it's at version 3.10.5.

Rerunning topostats process in /tests/resources/ will now output the files correctly.

Copy of the log-file from running with topostats --log-level debug <command>

[Mon, 04 Aug 2025 12:16:56] [INFO    ] [topostats] The YAML configuration file is valid.
[Mon, 04 Aug 2025 12:16:56] [INFO    ] [topostats] The YAML plotting configuration file is valid.
[Mon, 04 Aug 2025 12:16:56] [INFO    ] [topostats] Configuration run options are consistent, processing can proceed.
[Mon, 04 Aug 2025 12:16:56] [INFO    ] [topostats] Configuration file loaded from      : None
[Mon, 04 Aug 2025 12:16:56] [INFO    ] [topostats] Scanning for images in              : C:\Users\tobya\Documents\Work\TopoStats\TopoStats\tests\resources
[Mon, 04 Aug 2025 12:16:56] [INFO    ] [topostats] Output directory                    : output
[Mon, 04 Aug 2025 12:16:56] [INFO    ] [topostats] Looking for images with extension   : .spm
[Mon, 04 Aug 2025 12:16:56] [INFO    ] [topostats] Images with extension .spm in C:\Users\tobya\Documents\Work\TopoStats\TopoStats\tests\resources : 1
[Mon, 04 Aug 2025 12:16:56] [INFO    ] [topostats] Thresholding method (Filtering)     : std_dev
[Mon, 04 Aug 2025 12:16:56] [INFO    ] [topostats] Thresholding method (Grains)        : std_dev
[Mon, 04 Aug 2025 12:16:56] [INFO    ] [topostats] Extracting image from C:\Users\tobya\Documents\Work\TopoStats\TopoStats\tests\resources\minicircle.spm
12:16:56 | INFO |spm.py:spm:load_spm:80 | Loading image from : C:\Users\tobya\Documents\Work\TopoStats\TopoStats\tests\resources\minicircle.spm
12:16:56 | INFO |spm.py:spm:load_spm:85 | [minicircle] : Loaded image from : C:\Users\tobya\Documents\Work\TopoStats\TopoStats\tests\resources\minicircle.spm
12:16:56 | INFO |spm.py:spm:load_spm:87 | [minicircle] : Extracted channel Height
12:16:56 | INFO |spm.py:spm:spm_pixel_to_nm_scaling:44 | [minicircle] : Pixel to nm scaling : 0.4940029296875
Processing images from C:\Users\tobya\Documents\Work\TopoStats\TopoStats\tests\resources, results are under output:   0%| | 0/1 [00:00[Mon, 04 Aug 2025 12:17:01] [INFO    ] [topostats] Processing : minicircle
[Mon, 04 Aug 2025 12:17:01] [INFO    ] [topostats] [minicircle] : *** Filtering ***
[Mon, 04 Aug 2025 12:17:04] [INFO    ] [topostats] [minicircle] : Plotting Filtering Images
Processing images from C:\Users\tobya\Documents\Work\TopoStats\TopoStats\tests\resources, results are under output:   0%| | 0/1 [00:08
multiprocessing.pool.RemoteTraceback:
"""
Traceback (most recent call last):
  File "C:\Users\tobya\AppData\Local\Programs\Python\Python310\lib\multiprocessing\pool.py", line 125, in worker
    result = (True, func(*args, **kwds))
  File "C:\Users\tobya\Documents\Work\TopoStats\TopoStats\venv310\lib\site-packages\topostats\processing.py", line 1111, in process_scan
    image_flattened = run_filters(
  File "C:\Users\tobya\Documents\Work\TopoStats\TopoStats\venv310\lib\site-packages\topostats\processing.py", line 123, in run_filters
    ).plot_and_save()
  File "C:\Users\tobya\Documents\Work\TopoStats\TopoStats\venv310\lib\site-packages\topostats\plottingfuncs.py", line 517, in plot_and_save
    fig, ax = self.save_figure()
  File "C:\Users\tobya\Documents\Work\TopoStats\TopoStats\venv310\lib\site-packages\topostats\plottingfuncs.py", line 535, in save_figure
    fig, ax = plt.subplots(1, 1)
  File "C:\Users\tobya\Documents\Work\TopoStats\TopoStats\venv310\lib\site-packages\matplotlib\pyplot.py", line 1759, in subplots
    fig = figure(**fig_kw)
  File "C:\Users\tobya\Documents\Work\TopoStats\TopoStats\venv310\lib\site-packages\matplotlib\pyplot.py", line 1027, in figure
    manager = new_figure_manager(
  File "C:\Users\tobya\Documents\Work\TopoStats\TopoStats\venv310\lib\site-packages\matplotlib\pyplot.py", line 550, in new_figure_manager
    return _get_backend_mod().new_figure_manager(*args, **kwargs)
  File "C:\Users\tobya\Documents\Work\TopoStats\TopoStats\venv310\lib\site-packages\matplotlib\backend_bases.py", line 3507, in new_figure_manager
    return cls.new_figure_manager_given_figure(num, fig)
  File "C:\Users\tobya\Documents\Work\TopoStats\TopoStats\venv310\lib\site-packages\matplotlib\backend_bases.py", line 3512, in new_figure_manager_given_figure
    return cls.FigureCanvas.new_manager(figure, num)
  File "C:\Users\tobya\Documents\Work\TopoStats\TopoStats\venv310\lib\site-packages\matplotlib\backend_bases.py", line 1797, in new_manager
    return cls.manager_class.create_with_canvas(cls, figure, num)
  File "C:\Users\tobya\Documents\Work\TopoStats\TopoStats\venv310\lib\site-packages\matplotlib\backends\_backend_tk.py", line 504, in create_with_canvas
    manager = cls(canvas, num, window)
  File "C:\Users\tobya\Documents\Work\TopoStats\TopoStats\venv310\lib\site-packages\matplotlib\backends\_backend_tk.py", line 457, in __init__
    super().__init__(canvas, num)
  File "C:\Users\tobya\Documents\Work\TopoStats\TopoStats\venv310\lib\site-packages\matplotlib\backend_bases.py", line 2655, in __init__
    self.toolbar = self._toolbar2_class(self.canvas)
  File "C:\Users\tobya\Documents\Work\TopoStats\TopoStats\venv310\lib\site-packages\matplotlib\backends\_backend_tk.py", line 624, in __init__
    self._buttons[text] = button = self._Button(
  File "C:\Users\tobya\Documents\Work\TopoStats\TopoStats\venv310\lib\site-packages\matplotlib\backends\_backend_tk.py", line 825, in _Button
    NavigationToolbar2Tk._set_image_for_button(self, b)
  File "C:\Users\tobya\Documents\Work\TopoStats\TopoStats\venv310\lib\site-packages\matplotlib\backends\_backend_tk.py", line 767, in _set_image_for_button
    im_alt = _recolor_icon(im, foreground)
  File "C:\Users\tobya\Documents\Work\TopoStats\TopoStats\venv310\lib\site-packages\matplotlib\backends\_backend_tk.py", line 754, in _recolor_icon
    return Image.fromarray(image_data, mode="RGBA")
  File "C:\Users\tobya\Documents\Work\TopoStats\TopoStats\venv310\lib\site-packages\PIL\Image.py", line 3314, in fromarray
    deprecate("'mode' parameter", 13)
  File "C:\Users\tobya\Documents\Work\TopoStats\TopoStats\venv310\lib\site-packages\PIL\_deprecate.py", line 68, in deprecate
    warnings.warn(
DeprecationWarning: 'mode' parameter is deprecated and will be removed in Pillow 13 (2026-10-15)
"""

The above exception was the direct cause of the following exception:


Traceback (most recent call last):
  File "C:\Users\tobya\AppData\Local\Programs\Python\Python310\lib\runpy.py", line 196, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "C:\Users\tobya\AppData\Local\Programs\Python\Python310\lib\runpy.py", line 86, in _run_code
    exec(code, run_globals)
  File "C:\Users\tobya\Documents\Work\TopoStats\TopoStats\venv310\Scripts\topostats.exe\__main__.py", line 7, in <module>
    sys.exit(entry_point())
  File "C:\Users\tobya\Documents\Work\TopoStats\TopoStats\venv310\lib\site-packages\topostats\entry_point.py", line 1211, in entry_point
    args.func(args)
  File "C:\Users\tobya\Documents\Work\TopoStats\TopoStats\venv310\lib\site-packages\topostats\run_modules.py", line 252, in process
    for (
  File "C:\Users\tobya\AppData\Local\Programs\Python\Python310\lib\multiprocessing\pool.py", line 870, in next
    raise value
DeprecationWarning: 'mode' parameter is deprecated and will be removed in Pillow 13 (2026-10-15)

Include the configuration file

To Reproduce

 topostats process

TopoStats Version

Git main branch

Python Version

3.10

Operating System

Windows

Python Packages

absl-py==2.3.1
AFMReader==0.0.6
art==6.5
asttokens==3.0.0
astunparse==1.6.3
biopython==1.85
certifi==2025.8.3
charset-normalizer==3.4.2
cheap_repr==0.5.2
colorama==0.4.6
contourpy==1.3.3
cycler==0.12.1
decorator==5.2.1
docstring_parser==0.17.0
et_xmlfile==2.0.0
executing==2.2.0
flatbuffers==25.2.10
fonttools==4.59.0
gast==0.6.0
google-pasta==0.2.0
grpcio==1.74.0
h5py==3.14.0
idna==3.10
igor2==0.5.12
imageio==2.37.0
ipython==8.37.0
jedi==0.19.2
joblib==1.5.1
keras==3.11.1
kiwisolver==1.4.8
lazy_loader==0.4
libclang==18.1.1
llvmlite==0.44.0
loguru==0.7.3
magicgui==0.10.1
Markdown==3.8.2
markdown-it-py==3.0.0
MarkupSafe==3.0.2
matplotlib==3.9.4
matplotlib-inline==0.1.7
mdurl==0.1.2
ml_dtypes==0.5.3
namex==0.1.0
networkx==3.5
numba==0.61.2
numpy==2.1.3
numpyencoder==0.3.2
openpyxl==3.1.5
opt_einsum==3.4.0
optree==0.17.0
packaging==25.0
pandas==2.3.1
parso==0.8.4
pillow==11.3.0
prompt_toolkit==3.0.51
protobuf==5.29.5
psutil==5.9.8
psygnal==0.14.0
pure_eval==0.2.3
pyconify==0.2.1
Pygments==2.19.2
pyparsing==3.2.3
pyspm==0.6.3
python-dateutil==2.9.0.post0
pytz==2025.2
PyYAML==6.0.2
QtPy==2.4.3
requests==2.32.4
rich==14.1.0
ruamel.yaml==0.18.14
ruamel.yaml.clib==0.2.12
schema==0.7.7
scikit-image==0.25.2
scikit-learn==1.7.1
scipy==1.16.1
seaborn==0.13.2
six==1.17.0
skan==0.13.0
snoop==0.6.0
stack-data==0.6.3
superqt==0.7.5
tensorboard==2.19.0
tensorboard-data-server==0.7.2
tensorflow==2.19.0
tensorflow-io-gcs-filesystem==0.31.0
termcolor==3.1.0
threadpoolctl==3.6.0
tifffile==2025.6.11
toolz==1.0.0
topoly==1.1.0
topostats==2.3.1
tqdm==4.67.1
traitlets==5.14.3
typing_extensions==4.14.1
tzdata==2025.2
urllib3==2.5.0
wcwidth==0.2.13
Werkzeug==3.1.3
win32_setctime==1.2.0
wrapt==1.17.2

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions