Skip to content

Commit

Permalink
Implement Butler.get for matplotlib generated png files
Browse files Browse the repository at this point in the history
  • Loading branch information
fred3m committed Aug 11, 2023
1 parent 42f2c38 commit 0078c8a
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 3 deletions.
3 changes: 3 additions & 0 deletions mypy.ini
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ ignore_missing_imports = True
[mypy-numpy.*]
ignore_missing_imports = True

[mypy-matplotlib.*]
ignore_missing_imports = True

[mypy-pyarrow.*]
ignore_missing_imports = True

Expand Down
4 changes: 4 additions & 0 deletions python/lsst/daf/butler/configs/storageClasses.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -342,10 +342,14 @@ storageClasses:
dict: lsst.utils.packages.Packages
NumpyArray:
pytype: numpy.ndarray
converters:
matplotlib.figure.Figure: lsst.daf.butler.formatters.matplotlib.MatplotlibFormatter.dummyConverter
Thumbnail:
pytype: numpy.ndarray
Plot:
pytype: matplotlib.figure.Figure
converters:
numpy.ndarray: lsst.daf.butler.formatters.matplotlib.MatplotlibFormatter.fromArray
MetricValue:
pytype: lsst.verify.Measurement
StampsBase:
Expand Down
19 changes: 18 additions & 1 deletion python/lsst/daf/butler/formatters/matplotlib.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@

from typing import Any

import matplotlib.pyplot as plt
import numpy as np

from .file import FileFormatter


Expand All @@ -38,8 +41,22 @@ class MatplotlibFormatter(FileFormatter):

def _readFile(self, path: str, pytype: type[Any] | None = None) -> Any:
# docstring inherited from FileFormatter._readFile
raise NotImplementedError(f"matplotlib figures cannot be read by the butler; path is {path}")
return plt.imread(path)

def _writeFile(self, inMemoryDataset: Any) -> None:
# docstring inherited from FileFormatter._writeFile
inMemoryDataset.savefig(self.fileDescriptor.location.path)

@staticmethod
def fromArray(cls: np.ndarray) -> plt.Figure:
"""Convert an array into a Figure."""
fig = plt.figure()
plt.imshow(cls)
return fig

@staticmethod
def dummyCovnerter(cls: np.ndarray) -> np.ndarray:
"""This converter exists to trick the Butler into allowing
a numpy array on read with ``storageClass='NumpyArray'``.
"""

Check failure on line 61 in python/lsst/daf/butler/formatters/matplotlib.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (D401)

python/lsst/daf/butler/formatters/matplotlib.py:59:9: D401 First line of docstring should be in imperative mood: "This converter exists to trick the Butler into allowing"

Check failure on line 61 in python/lsst/daf/butler/formatters/matplotlib.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (D404)

python/lsst/daf/butler/formatters/matplotlib.py:59:9: D404 First word of the docstring should not be "This"
return cls

Check warning on line 62 in python/lsst/daf/butler/formatters/matplotlib.py

View check run for this annotation

Codecov / codecov/patch

python/lsst/daf/butler/formatters/matplotlib.py#L62

Added line #L62 was not covered by tests
11 changes: 9 additions & 2 deletions tests/test_matplotlibFormatter.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
import unittest
from random import Random

import numpy as np

try:
import matplotlib

Expand Down Expand Up @@ -78,8 +80,13 @@ def testMatplotlibFormatter(self):
pyplot.gcf().savefig(file.name)
self.assertTrue(filecmp.cmp(local.ospath, file.name, shallow=True))
self.assertTrue(butler.exists(ref))
with self.assertRaises(ValueError):
butler.get(ref)

fig = butler.get(ref)
# Ensure that the result is a figure
self.assertTrue(isinstance(fig, pyplot.Figure))
image = butler.get(ref, storageClass="NumpyArray")
self.assertTrue(isinstance(image, np.ndarray))

butler.pruneDatasets([ref], unstore=True, purge=True)
self.assertFalse(butler.exists(ref))

Expand Down

0 comments on commit 0078c8a

Please sign in to comment.