napari / napari-svg

A plugin for writing svg files from napari
BSD 3-Clause "New" or "Revised" License
4 stars 12 forks source link

Cannot write SVGs of images with 'gray' colormap #13

Closed kevinyamauchi closed 4 years ago

kevinyamauchi commented 4 years ago

Description As described in #12, napari uses gray, a matplotlib colormap the default. While this works in napari, since the matplotlib colormaps have been vendored, this does not work here because the SVG writer uses the vispy get_colormap() function, which depends on matplotlib for the grayscale colormap is called gray (see here). vispy however, does support a grayscale colormap called 'grays' without matplotlib.

Possible fixes

  1. The quickest, but hackiest fix is to convert gray to grays for this plugin. Although, now that I think about it, there are probably other colormaps that would fail for the same reason...probably not the best fix.
  2. We could vendor the matplotlib colormaps here as well.
  3. We could make napari a dependency of this plugin and use the colormap machinery from there.
  4. This is a heavy solution, but we could add matplotlib as a dependency for this plugin.

Option 3 seems like the easiest thing to do for now, but it nice conceptually that napari plugins don't rely on napari. That being said, moving to our own colormap system is on the roadmap, so this would likely be a somewhat temporary thing. Further, for now, I think pretty much everyone is going to use this plugin as it comes with napari, so it's probably not a big deal to make napari a dependency.

To reproduce:

With napari installed from pip in a fresh environment:

import napari
import numpy as np

data = np.random.rand(100,100)

with napari.gui_qt():
    # create the viewer with an image
    viewer = napari.view_image(data, colormap='gray')

    viewer.layers['data'].save('test.svg')

Gives the following error:

 File "test_image.py", line 10, in <module>
    viewer.layers['data'].save('test.svg')
  File "/Users/yamauc0000/Documents/napari_test/.venv/lib/python3.7/site-packages/napari/layers/base/base.py", line 748, in save
    return save_layers(path, [self], plugin=plugin)
  File "/Users/yamauc0000/Documents/napari_test/.venv/lib/python3.7/site-packages/napari/plugins/io.py", line 176, in save_layers
    path, layers[0], plugin_name=plugin
  File "/Users/yamauc0000/Documents/napari_test/.venv/lib/python3.7/site-packages/napari/plugins/io.py", line 334, in _write_single_layer_with_plugins
    meta=layer._get_state(),
  File "/Users/yamauc0000/Documents/napari_test/.venv/lib/python3.7/site-packages/napari_plugin_engine/hooks.py", line 506, in __call__
    result = self.call_with_result_obj(_skip_impls=_skip_impls, **kwargs)
  File "/Users/yamauc0000/Documents/napari_test/.venv/lib/python3.7/site-packages/napari_plugin_engine/hooks.py", line 447, in call_with_result_obj
    return self._hookexec(self, impls, kwargs)
  File "/Users/yamauc0000/Documents/napari_test/.venv/lib/python3.7/site-packages/napari_plugin_engine/manager.py", line 147, in _hookexec
    return self._inner_hookexec(caller, methods, kwargs)
  File "/Users/yamauc0000/Documents/napari_test/.venv/lib/python3.7/site-packages/napari_plugin_engine/manager.py", line 109, in <lambda>
    m, k, firstresult=c.is_firstresult
  File "/Users/yamauc0000/Documents/napari_test/.venv/lib/python3.7/site-packages/napari_plugin_engine/callers.py", line 210, in _multicall
    raise errors[-1]
napari_plugin_engine.exceptions.PluginCallError: Error in plugin 'svg', hook 'napari_write_image': 'colormap name gray not found'
kevinyamauchi commented 4 years ago

Ah, I am seeing #5 now. If we are okay with all in matplotlib, but not in vispy colormaps failing except for gray, I think we can do option 1 for now.

sofroniewn commented 4 years ago

Yeah, let's do option 1 which maybe some try/ catch that if a colormap isn't found you just get grays. Right now the labels layer just uses grays which is kind of terrible, but survivable.

We could do option 3 depending on how long it takes to address #5, but for now the quick solution is ok I think

kevinyamauchi commented 4 years ago

Sounds good. I will implement this in #12 !

kevinyamauchi commented 4 years ago

Closed by #12