Skip to content

Commit

Permalink
Merge pull request #3820 from neutrinoceros/hotfix_3819
Browse files Browse the repository at this point in the history
BUG: fix plot bounds for slices in cylindrical coordinates
  • Loading branch information
matthewturk authored Mar 11, 2022
2 parents c54c585 + 6be4799 commit ef08989
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 50 deletions.
48 changes: 48 additions & 0 deletions yt/geometry/coordinates/coordinate_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -386,3 +386,51 @@ def cylindrical_to_cartesian(coord, center=(0, 0, 0)):
c2[..., 1] = np.sin(coord[..., 0]) * coord[..., 1] + center[1]
c2[..., 2] = coord[..., 2]
return c2


def _get_polar_bounds(self: CoordinateHandler, axes: Tuple[str, str]):
# a small helper function that is needed by two unrelated classes
ri = self.axis_id[axes[0]]
pi = self.axis_id[axes[1]]
rmin = self.ds.domain_left_edge[ri]
rmax = self.ds.domain_right_edge[ri]
phimin = self.ds.domain_left_edge[pi]
phimax = self.ds.domain_right_edge[pi]
corners = [
(rmin, phimin),
(rmin, phimax),
(rmax, phimin),
(rmax, phimax),
]

def to_polar_plane(r, phi):
x = r * np.cos(phi)
y = r * np.sin(phi)
return x, y

conic_corner_coords = [to_polar_plane(*corner) for corner in corners]

phimin = phimin.d
phimax = phimax.d

if phimin <= np.pi <= phimax:
xxmin = -rmax
else:
xxmin = min(xx for xx, yy in conic_corner_coords)

if phimin <= 0 <= phimax:
xxmax = rmax
else:
xxmax = max(xx for xx, yy in conic_corner_coords)

if phimin <= 3 * np.pi / 2 <= phimax:
yymin = -rmax
else:
yymin = min(yy for xx, yy in conic_corner_coords)

if phimin <= np.pi / 2 <= phimax:
yymax = rmax
else:
yymax = max(yy for xx, yy in conic_corner_coords)

return xxmin, xxmax, yymin, yymax
36 changes: 30 additions & 6 deletions yt/geometry/coordinates/cylindrical_coordinates.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
import sys

import numpy as np

from yt.utilities.lib.pixelization_routines import pixelize_cartesian, pixelize_cylinder

if sys.version_info >= (3, 8):
from functools import cached_property
else:
from yt._maintenance.backports import cached_property

from .coordinate_handler import (
CoordinateHandler,
_get_coord_fields,
_get_polar_bounds,
_setup_dummy_cartesian_coords_and_widths,
_setup_polar_coordinates,
cartesian_to_cylindrical,
Expand Down Expand Up @@ -94,6 +102,13 @@ def pixelize(
data_source, field, bounds, size, antialias, dimension, periodic
)
elif ax_name == "z":
# This is admittedly a very hacky way to resolve a bug
# it's very likely that the *right* fix would have to
# be applied upstream of this function, *but* this case
# has never worked properly so maybe it's still preferable to
# not having a solution ?
# see https://github.com/yt-project/yt/pull/3533
bounds = (*bounds[2:4], *bounds[:2])
return self._cyl_pixelize(data_source, field, bounds, size, antialias)
else:
# Pixelizing along a cylindrical surface is a bit tricky
Expand Down Expand Up @@ -152,7 +167,7 @@ def image_axis_name(self):
# non-Cartesian coordinates, we usually want to override these for
# Cartesian coordinates, since we transform them.
rv = {
self.axis_id["r"]: ("theta", "z"),
self.axis_id["r"]: ("\\theta", "z"),
self.axis_id["z"]: ("x", "y"),
self.axis_id["theta"]: ("r", "z"),
}
Expand Down Expand Up @@ -184,6 +199,10 @@ def convert_from_spherical(self, coord):
def period(self):
return np.array([0.0, 0.0, 2.0 * np.pi])

@cached_property
def _polar_bounds(self):
return _get_polar_bounds(self, axes=("r", "theta"))

def sanitize_center(self, center, axis):
center, display_center = super().sanitize_center(center, axis)
display_center = [
Expand All @@ -202,6 +221,11 @@ def sanitize_center(self, center, axis):
# use existing center value
for idx in (r_ax, z_ax):
display_center[idx] = center[idx]
elif ax_name == "z":
xxmin, xxmax, yymin, yymax = self._polar_bounds
xc = (xxmin + xxmax) / 2
yc = (yymin + yymax) / 2
display_center = (xc, yc, 0 * xc)
return center, display_center

def sanitize_width(self, axis, width, depth):
Expand All @@ -214,12 +238,12 @@ def sanitize_width(self, axis, width, depth):
# Note: regardless of axes, these are set up to give consistent plots
# when plotted, which is not strictly a "right hand rule" for axes.
elif name == "r": # soup can label
width = [2.0 * np.pi * self.ds.domain_width.uq, self.ds.domain_width[z_ax]]
width = [self.ds.domain_width[theta_ax], self.ds.domain_width[z_ax]]
elif name == "theta":
width = [self.ds.domain_width[r_ax], self.ds.domain_width[z_ax]]
elif name == "z":
width = [
2.0 * self.ds.domain_right_edge[r_ax],
2.0 * self.ds.domain_right_edge[r_ax],
]
xxmin, xxmax, yymin, yymax = self._polar_bounds
xw = xxmax - xxmin
yw = yymax - yymin
width = [xw, yw]
return width
46 changes: 2 additions & 44 deletions yt/geometry/coordinates/spherical_coordinates.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from .coordinate_handler import (
CoordinateHandler,
_get_coord_fields,
_get_polar_bounds,
_setup_dummy_cartesian_coords_and_widths,
_setup_polar_coordinates,
)
Expand Down Expand Up @@ -275,50 +276,7 @@ def to_poloidal_plane(r, theta):

@cached_property
def _conic_bounds(self):
ri = self.axis_id["r"]
pi = self.axis_id["phi"]
rmin = self.ds.domain_left_edge[ri]
rmax = self.ds.domain_right_edge[ri]
phimin = self.ds.domain_left_edge[pi]
phimax = self.ds.domain_right_edge[pi]
corners = [
(rmin, phimin),
(rmin, phimax),
(rmax, phimin),
(rmax, phimax),
]

def to_conic_plane(r, phi):
x = r * np.cos(phi)
y = r * np.sin(phi)
return x, y

conic_corner_coords = [to_conic_plane(*corner) for corner in corners]

phimin = phimin.d
phimax = phimax.d

if phimin <= np.pi <= phimax:
xxmin = -rmax
else:
xxmin = min(xx for xx, yy in conic_corner_coords)

if phimin <= 0 <= phimax:
xxmax = rmax
else:
xxmax = max(xx for xx, yy in conic_corner_coords)

if phimin <= 3 * np.pi / 2 <= phimax:
yymin = -rmax
else:
yymin = min(yy for xx, yy in conic_corner_coords)

if phimin <= np.pi / 2 <= phimax:
yymax = rmax
else:
yymax = max(yy for xx, yy in conic_corner_coords)

return xxmin, xxmax, yymin, yymax
return _get_polar_bounds(self, axes=("r", "phi"))

@cached_property
def _aitoff_bounds(self):
Expand Down
2 changes: 2 additions & 0 deletions yt/visualization/plot_window.py
Original file line number Diff line number Diff line change
Expand Up @@ -1952,6 +1952,7 @@ def __init__(
"cylindrical",
"geographic",
"internal_geographic",
"polar",
):
mylog.info("Setting origin='native' for %s geometry.", ds.geometry)
origin = "native"
Expand Down Expand Up @@ -2167,6 +2168,7 @@ def __init__(
"cylindrical",
"geographic",
"internal_geographic",
"polar",
):
mylog.info("Setting origin='native' for %s geometry.", ds.geometry)
origin = "native"
Expand Down

0 comments on commit ef08989

Please sign in to comment.