Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhanced map plot results in bad pixel scaling #772

Open
prajwel opened this issue Apr 7, 2022 · 5 comments
Open

Enhanced map plot results in bad pixel scaling #772

prajwel opened this issue Apr 7, 2022 · 5 comments

Comments

@prajwel
Copy link

prajwel commented Apr 7, 2022

Hi,

Thank you for maintaining this excellent software. I would like to report the following problem.

The enhanced map plot results in bad pixel scaling.

To reproduce the problem, please run the following script

import marvin

target = "8485-1901"
maps = marvin.tools.Maps(target)
ha = maps.emline_gflux_ha_6564
hb = maps.emline_gflux_hb_4862
ha_hb = ha / hb
log_ha_hb = np.log10(ha_hb)

# Good scaling
ha_hb.plot()

Figure 1

# Bad scaling
log_ha_hb.plot()

Figure 2

Expected behaviour: the pixel colour scaling should be comparable to that produced by ha_hb.plot().

Could you please let me know if there is a way to correct this?

@bretthandrews
Copy link
Contributor

Hopefully the log_cb keyword should do the trick:

log_ha_hb.plot(log_cb=True)

@prajwel
Copy link
Author

prajwel commented Apr 8, 2022

log_ha_hb.plot(log_cb=True)

gives the following error.

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
/tmp/ipykernel_2243/3305198056.py in <module>
----> 1 log_ha_hb.plot(log_cb=True)

~/miniconda3/envs/py38/lib/python3.8/site-packages/marvin/tools/quantities/map.py in plot(self, *args, **kwargs)
    633     @add_doc(marvin.utils.plot.map.plot.__doc__)
    634     def plot(self, *args, **kwargs):
--> 635         return marvin.utils.plot.map.plot(dapmap=self, *args, **kwargs)
    636 
    637 

~/miniconda3/envs/py38/lib/python3.8/site-packages/marvin/utils/plot/map.py in plot(*args, **kwargs)
    509 
    510         # plot unmasked spaxels
--> 511         p = ax.imshow(good_spax, cmap=cb_kws['cmap'], zorder=10, **imshow_kws)
    512 
    513         fig, cb = colorbar._draw_colorbar(fig, mappable=p, ax=ax, **cb_kws)

~/miniconda3/envs/py38/lib/python3.8/site-packages/matplotlib/_api/deprecation.py in wrapper(*args, **kwargs)
    454                 "parameter will become keyword-only %(removal)s.",
    455                 name=name, obj_type=f"parameter of {func.__name__}()")
--> 456         return func(*args, **kwargs)
    457 
    458     # Don't modify *func*'s signature, as boilerplate.py needs it.

~/miniconda3/envs/py38/lib/python3.8/site-packages/matplotlib/__init__.py in inner(ax, data, *args, **kwargs)
   1410     def inner(ax, *args, data=None, **kwargs):
   1411         if data is None:
-> 1412             return func(ax, *map(sanitize_sequence, args), **kwargs)
   1413 
   1414         bound = new_sig.bind(ax, *args, **kwargs)

~/miniconda3/envs/py38/lib/python3.8/site-packages/matplotlib/axes/_axes.py in imshow(self, X, cmap, norm, aspect, interpolation, alpha, vmin, vmax, origin, extent, interpolation_stage, filternorm, filterrad, resample, url, **kwargs)
   5445             # image does not already have clipping set, clip to axes patch
   5446             im.set_clip_path(self.patch)
-> 5447         im._scale_norm(norm, vmin, vmax)
   5448         im.set_url(url)
   5449 

~/miniconda3/envs/py38/lib/python3.8/site-packages/matplotlib/cm.py in _scale_norm(self, norm, vmin, vmax)
    378             self.set_clim(vmin, vmax)
    379             if norm is not None:
--> 380                 raise ValueError(
    381                     "Passing parameters norm and vmin/vmax simultaneously is "
    382                     "not supported. Please pass vmin/vmax directly to the "

ValueError: Passing parameters norm and vmin/vmax simultaneously is not supported. Please pass vmin/vmax directly to the norm when creating it.

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
~/miniconda3/envs/py38/lib/python3.8/site-packages/IPython/core/formatters.py in __call__(self, obj, include, exclude)
    968 
    969             if method is not None:
--> 970                 return method(include=include, exclude=exclude)
    971             return None
    972         else:

~/miniconda3/envs/py38/lib/python3.8/site-packages/ipympl/backend_nbagg.py in _repr_mimebundle_(self, **kwargs)
    304 
    305         buf = io.BytesIO()
--> 306         self.figure.savefig(buf, format='png', dpi='figure')
    307         self._data_url = b64encode(buf.getvalue()).decode('utf-8')
    308         # Figure width in pixels

~/miniconda3/envs/py38/lib/python3.8/site-packages/matplotlib/figure.py in savefig(self, fname, transparent, **kwargs)
   3010                         ax.patch._cm_set(facecolor='none', edgecolor='none'))
   3011 
-> 3012             self.canvas.print_figure(fname, **kwargs)
   3013 
   3014     def ginput(self, n=1, timeout=30, show_clicks=True,

~/miniconda3/envs/py38/lib/python3.8/site-packages/matplotlib/backend_bases.py in print_figure(self, filename, dpi, facecolor, edgecolor, orientation, format, bbox_inches, pad_inches, bbox_extra_artists, backend, **kwargs)
   2312                 # force the figure dpi to 72), so we need to set it again here.
   2313                 with cbook._setattr_cm(self.figure, dpi=dpi):
-> 2314                     result = print_method(
   2315                         filename,
   2316                         facecolor=facecolor,

~/miniconda3/envs/py38/lib/python3.8/site-packages/matplotlib/backend_bases.py in wrapper(*args, **kwargs)
   1641             kwargs.pop(arg)
   1642 
-> 1643         return func(*args, **kwargs)
   1644 
   1645     return wrapper

~/miniconda3/envs/py38/lib/python3.8/site-packages/matplotlib/_api/deprecation.py in wrapper(*inner_args, **inner_kwargs)
    410                          else deprecation_addendum,
    411                 **kwargs)
--> 412         return func(*inner_args, **inner_kwargs)
    413 
    414     DECORATORS[wrapper] = decorator

~/miniconda3/envs/py38/lib/python3.8/site-packages/matplotlib/backends/backend_agg.py in print_png(self, filename_or_obj, metadata, pil_kwargs, *args)
    538             *metadata*, including the default 'Software' key.
    539         """
--> 540         FigureCanvasAgg.draw(self)
    541         mpl.image.imsave(
    542             filename_or_obj, self.buffer_rgba(), format="png", origin="upper",

~/miniconda3/envs/py38/lib/python3.8/site-packages/matplotlib/backends/backend_agg.py in draw(self)
    434              (self.toolbar._wait_cursor_for_draw_cm() if self.toolbar
    435               else nullcontext()):
--> 436             self.figure.draw(self.renderer)
    437             # A GUI class may be need to update a window using this draw, so
    438             # don't forget to call the superclass.

~/miniconda3/envs/py38/lib/python3.8/site-packages/matplotlib/artist.py in draw_wrapper(artist, renderer, *args, **kwargs)
     71     @wraps(draw)
     72     def draw_wrapper(artist, renderer, *args, **kwargs):
---> 73         result = draw(artist, renderer, *args, **kwargs)
     74         if renderer._rasterizing:
     75             renderer.stop_rasterizing()

~/miniconda3/envs/py38/lib/python3.8/site-packages/matplotlib/artist.py in draw_wrapper(artist, renderer)
     48                 renderer.start_filter()
     49 
---> 50             return draw(artist, renderer)
     51         finally:
     52             if artist.get_agg_filter() is not None:

~/miniconda3/envs/py38/lib/python3.8/site-packages/matplotlib/figure.py in draw(self, renderer)
   2801 
   2802             self.patch.draw(renderer)
-> 2803             mimage._draw_list_compositing_images(
   2804                 renderer, self, artists, self.suppressComposite)
   2805 

~/miniconda3/envs/py38/lib/python3.8/site-packages/matplotlib/image.py in _draw_list_compositing_images(renderer, parent, artists, suppress_composite)
    130     if not_composite or not has_images:
    131         for a in artists:
--> 132             a.draw(renderer)
    133     else:
    134         # Composite any adjacent images together

~/miniconda3/envs/py38/lib/python3.8/site-packages/matplotlib/artist.py in draw_wrapper(artist, renderer)
     48                 renderer.start_filter()
     49 
---> 50             return draw(artist, renderer)
     51         finally:
     52             if artist.get_agg_filter() is not None:

~/miniconda3/envs/py38/lib/python3.8/site-packages/matplotlib/axes/_base.py in draw(self, renderer)
   3080             renderer.stop_rasterizing()
   3081 
-> 3082         mimage._draw_list_compositing_images(
   3083             renderer, self, artists, self.figure.suppressComposite)
   3084 

~/miniconda3/envs/py38/lib/python3.8/site-packages/matplotlib/image.py in _draw_list_compositing_images(renderer, parent, artists, suppress_composite)
    130     if not_composite or not has_images:
    131         for a in artists:
--> 132             a.draw(renderer)
    133     else:
    134         # Composite any adjacent images together

~/miniconda3/envs/py38/lib/python3.8/site-packages/matplotlib/artist.py in draw_wrapper(artist, renderer)
     48                 renderer.start_filter()
     49 
---> 50             return draw(artist, renderer)
     51         finally:
     52             if artist.get_agg_filter() is not None:

~/miniconda3/envs/py38/lib/python3.8/site-packages/matplotlib/image.py in draw(self, renderer, *args, **kwargs)
    644                 renderer.draw_image(gc, l, b, im, trans)
    645         else:
--> 646             im, l, b, trans = self.make_image(
    647                 renderer, renderer.get_image_magnification())
    648             if im is not None:

~/miniconda3/envs/py38/lib/python3.8/site-packages/matplotlib/image.py in make_image(self, renderer, magnification, unsampled)
    954         clip = ((self.get_clip_box() or self.axes.bbox) if self.get_clip_on()
    955                 else self.figure.bbox)
--> 956         return self._make_image(self._A, bbox, transformed_bbox, clip,
    957                                 magnification, unsampled=unsampled)
    958 

~/miniconda3/envs/py38/lib/python3.8/site-packages/matplotlib/image.py in _make_image(self, A, in_bbox, out_bbox, clip_bbox, magnification, unsampled, round_to_pixel_border)
    545                                            vmax=s_vmax,
    546                                            ):
--> 547                         output = self.norm(resampled_masked)
    548             else:
    549                 if A.ndim == 2:  # _interpolation_stage == 'rgba'

~/miniconda3/envs/py38/lib/python3.8/site-packages/matplotlib/colors.py in __call__(self, value, clip)
   1529             self.autoscale_None(value)
   1530             if self.vmin > self.vmax:
-> 1531                 raise ValueError("vmin must be less or equal to vmax")
   1532             if self.vmin == self.vmax:
   1533                 return np.full_like(value, 0)

ValueError: vmin must be less or equal to vmax

Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous view', 'arrow-left', 'back'), ('Forward', 'Forward to next view', 'arrow-right', 'forward'), ('Pan', 'Left button pans, Right button zooms\nx/y fixes axis, CTRL fixes aspect', 'arrows', 'pan'), ('Zoom', 'Zoom to rectangle\nx/y fixes axis', 'square-o', 'zoom'), ('Download', 'Download plot', 'floppy-o', 'save_figure')]))

@havok2063
Copy link
Collaborator

Which version of sdss-marvin, and matplotlib do you have installed?

@prajwel
Copy link
Author

prajwel commented Apr 9, 2022

I am using the Marvin image on SciServer. The versions are as follows.

marvin: 2.7.1
matplotlib: 3.5.0

@bretthandrews
Copy link
Contributor

Right! I believe that the issue is that the signal-to-noise mask doesn't play well with log quantities. One way around this is to set snr_min=-1000 or something low enough to not cut any good data. The other way is to use the linear ratio and use a log-scaled colorbar: ha_hb.plot(log_cb=True).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants