marvin
marvin copied to clipboard
Enhanced map plot results in bad pixel scaling
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()
# Bad scaling
log_ha_hb.plot()
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?
Hopefully the log_cb
keyword should do the trick:
log_ha_hb.plot(log_cb=True)
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')]))
Which version of sdss-marvin
, and matplotlib
do you have installed?
I am using the Marvin image on SciServer. The versions are as follows.
marvin: 2.7.1
matplotlib: 3.5.0
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)
.