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

Background not transparant for plotting in spherical coordinates (no log). #2480

Closed
chverbeke opened this issue Mar 13, 2020 · 6 comments · Fixed by #2517
Closed

Background not transparant for plotting in spherical coordinates (no log). #2480

chverbeke opened this issue Mar 13, 2020 · 6 comments · Fixed by #2517
Assignees
Labels
bug coordinates: non-cartesian viz: 2D yt-3.6 feature targeted for the yt-3.6 release

Comments

@chverbeke
Copy link

When plotting a slice, the parts of the plot that do not belong to the dataset are usually plotted to be transparant (or you can set the background color yourself).
However, when using spherical coordinates and not have a log_scale, this is not the case and the background is always set to lowest value of the colorbar. This is the case whether you pick the limits of your colorbar yourself or not, and also whether you set the background color yourself or not.

import yt
ds_fake = yt.testing.fake_amr_ds(geometry='spherical')
slice_fake_1 = yt.SlicePlot(ds_fake, axis='theta', fields='Density')
slice_fake_1.show()
slice_fake_2 = yt.SlicePlot(ds_fake, axis='theta', fields='Density')
slice_fake_2.set_log('Density', False)
slice_fake_2.show()

spherical_1
spherical_2

@welcome
Copy link

welcome bot commented Mar 13, 2020

Hi, and welcome to yt! Thanks for opening your first issue. We have an issue template that helps us to gather relevant information to help diagnosing and fixing the issue.

@triage-new-issues triage-new-issues bot added the triage Triage needed label Mar 13, 2020
@matthewturk
Copy link
Member

Hi! So this is happening because in the log valued, the background (0.0) values are getting turned into NaNs.

I am looking now at the code for how we might address this so that it masks regardless of the geometry and logging.

@matthewturk
Copy link
Member

I was able to make the behavior consistent with this patch:

diff --git a/yt/geometry/coordinates/spherical_coordinates.py b/yt/geometry/coordinates/spherical_coordinates.py
index 4f811af9c..5bc36f4ad 100644
--- a/yt/geometry/coordinates/spherical_coordinates.py
+++ b/yt/geometry/coordinates/spherical_coordinates.py
@@ -153,7 +153,7 @@ class SphericalCoordinateHandler(CoordinateHandler):
     def _cyl_pixelize(self, data_source, field, bounds, size, antialias,
                       dimension):
         name = self.axis_name[dimension]
-        buff = np.zeros((size[1], size[0]), dtype="f8")
+        buff = np.full((size[1], size[0]), np.nan, dtype="f8")
         if name == 'theta':
             pixelize_cylinder(buff,
                               data_source['px'],

Would you like to issue a pull request with this?

@chverbeke
Copy link
Author

Not sure if desired, but the fix now gives a RuntimeWarning for the log-scale case. The non-log scale works as intended indeed! Let me know if you want to fix this warning before issuing a pull request.

/Users/christine/.local/lib/python3.7/site-packages/matplotlib/colors.py:1110: RuntimeWarning: invalid value encountered in less_equal
  mask |= resdat <= 0

@matthewturk
Copy link
Member

matthewturk commented Mar 13, 2020 via email

@chverbeke
Copy link
Author

chverbeke commented Mar 13, 2020

Both cases (log and non-log) now give similar errors, see below (except for the RuntimeWarning which is only in the log-scale case).
However, I also tried with np.inf instead of -np.inf and that seems to run fine for the fake_amr_ds case and my own data. Not sure if this may give problems for certain other datasets though?

`/Users/christine/.local/lib/python3.7/site-packages/matplotlib/colors.py:1211: RuntimeWarning: invalid value encountered in greater
masked = np.abs(a) > (self.linthresh * self._linscale_adj)

ValueError Traceback (most recent call last)
in
2 yt.mylog.setLevel(50)
3 ds_fake = yt.testing.fake_amr_ds(geometry='spherical')
----> 4 slice_fake_1 = yt.SlicePlot(ds_fake, axis='theta', fields='Density')
5 slice_fake_1.show()

~/yt/yt/visualization/plot_window.py in SlicePlot(ds, normal, fields, axis, *args, **kwargs)
1972 del kwargs['north_vector']
1973
-> 1974 return AxisAlignedSlicePlot(ds, normal, fields, *args, **kwargs)
1975
1976 def plot_2d(ds, fields, center='c', width=None, axes_unit=None,

~/yt/yt/visualization/plot_window.py in init(self, ds, axis, fields, center, width, axes_unit, origin, right_handed, fontsize, field_parameters, window_size, aspect, data_source)
1281 fontsize=fontsize, fields=fields,
1282 window_size=window_size, aspect=aspect,
-> 1283 right_handed=right_handed)
1284 if axes_unit is None:
1285 axes_unit = get_axes_unit(width, ds)

~/yt/yt/visualization/plot_window.py in init(self, *args, **kwargs)
774 self._plot_type = kwargs.pop("plot_type")
775 self._splat_color = kwargs.pop("splat_color", None)
--> 776 PlotWindow.init(self, *args, **kwargs)
777
778 def _setup_origin(self):

~/yt/yt/visualization/plot_window.py in init(self, data_source, bounds, buff_size, antialias, periodic, origin, oblique, right_handed, window_size, fields, fontsize, aspect, setup)
227 self._field_transform[field] = linear_transform
228 self.setup_callbacks()
--> 229 self._setup_plots()
230
231 def iter(self):

~/yt/yt/visualization/plot_window.py in _setup_plots(self)
964 self.figure_size, font_size,
965 self.aspect, fig, axes, cax, self._projection,
--> 966 self._transform)
967
968 if not self._right_handed:

~/yt/yt/visualization/plot_window.py in init(self, data, cbname, cblinthresh, cmap, extent, zlim, figure_size, fontsize, aspect, figure, axes, cax, mpl_proj, mpl_transform)
1777 size, axrect, caxrect, zlim, figure, axes, cax)
1778
-> 1779 self._init_image(data, cbname, cblinthresh, cmap, extent, aspect)
1780
1781 # In matplotlib 2.1 and newer we'll be able to do this using

~/yt/yt/visualization/base_plot_types.py in _init_image(self, data, cbnorm, cblinthresh, cmap, extent, aspect)
265 **formatter_kwargs)
266 self.cb = self.figure.colorbar(
--> 267 self.image, self.cax, format=formatter)
268 if np.nanmin(data) >= 0.0:
269 yticks = [np.nanmin(data).v] + list(

~/.local/lib/python3.7/site-packages/matplotlib/figure.py in colorbar(self, mappable, cax, ax, use_gridspec, **kw)
2213 'panchor']
2214 cb_kw = {k: v for k, v in kw.items() if k not in NON_COLORBAR_KEYS}
-> 2215 cb = cbar.colorbar_factory(cax, mappable, **cb_kw)
2216
2217 self.sca(current_ax)

~/.local/lib/python3.7/site-packages/matplotlib/colorbar.py in colorbar_factory(cax, mappable, **kwargs)
1638 cb = ColorbarPatch(cax, mappable, **kwargs)
1639 else:
-> 1640 cb = Colorbar(cax, mappable, **kwargs)
1641
1642 cid = mappable.callbacksSM.connect('changed', cb.on_mappable_changed)

~/.local/lib/python3.7/site-packages/matplotlib/colorbar.py in init(self, ax, mappable, **kw)
1181 kw['alpha'] = mappable.get_alpha()
1182
-> 1183 ColorbarBase.init(self, ax, **kw)
1184
1185 def on_mappable_changed(self, mappable):

~/.local/lib/python3.7/site-packages/matplotlib/colorbar.py in init(self, ax, cmap, norm, alpha, values, boundaries, orientation, ticklocation, extend, spacing, ticks, format, drawedges, filled, extendfrac, extendrect, label)
458 else:
459 self.formatter = format # Assume it is a Formatter or None
--> 460 self.draw_all()
461
462 def _extend_lower(self):

~/.local/lib/python3.7/site-packages/matplotlib/colorbar.py in draw_all(self)
491 C = self._values[:, np.newaxis]
492 self.config_axis()
--> 493 self._config_axes(X, Y)
494 if self.filled:
495 self._add_solids(X, Y, C)

~/.local/lib/python3.7/site-packages/matplotlib/colorbar.py in _config_axes(self, X, Y)
725 ax.add_artist(self.patch)
726
--> 727 self.update_ticks()
728
729 def _set_label(self):

~/.local/lib/python3.7/site-packages/matplotlib/colorbar.py in update_ticks(self)
612 else:
613 _log.debug('Using fixed locator on colorbar')
--> 614 ticks, ticklabels, offset_string = self._ticker(locator, formatter)
615 long_axis.set_ticks(ticks)
616 long_axis.set_ticklabels(ticklabels)

~/.local/lib/python3.7/site-packages/matplotlib/colorbar.py in _ticker(self, locator, formatter)
848 formatter.set_data_interval(*intv)
849
--> 850 b = np.array(locator())
851 if isinstance(locator, ticker.LogLocator):
852 eps = 1e-10

~/.local/lib/python3.7/site-packages/matplotlib/ticker.py in call(self)
2437 # Note, these are untransformed coordinates
2438 vmin, vmax = self.axis.get_view_interval()
-> 2439 return self.tick_values(vmin, vmax)
2440
2441 def tick_values(self, vmin, vmax):

~/.local/lib/python3.7/site-packages/matplotlib/ticker.py in tick_values(self, vmin, vmax)
2525
2526 if has_c:
-> 2527 decades.extend(b ** (np.arange(c_range[0], c_range[1], stride)))
2528
2529 # Add the subticks if requested

ValueError: arange: cannot compute length`

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug coordinates: non-cartesian viz: 2D yt-3.6 feature targeted for the yt-3.6 release
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants