Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 5 additions & 52 deletions control/grid.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,53 +31,6 @@ def __call__(self, direction, factor, values):
return ret


class ModifiedExtremeFinderCycle(angle_helper.ExtremeFinderCycle):
"""Changed to allow only left hand-side polar grid.

https://matplotlib.org/_modules/mpl_toolkits/axisartist/angle_helper.html#ExtremeFinderCycle.__call__
"""
def __call__(self, transform_xy, x1, y1, x2, y2):
x, y = np.meshgrid(
np.linspace(x1, x2, self.nx), np.linspace(y1, y2, self.ny))
lon, lat = transform_xy(np.ravel(x), np.ravel(y))

with np.errstate(invalid='ignore'):
if self.lon_cycle is not None:
lon0 = np.nanmin(lon)
# Changed from 180 to 360 to be able to span only
# 90-270 (left hand side)
lon -= 360. * ((lon - lon0) > 360.)
if self.lat_cycle is not None: # pragma: no cover
lat0 = np.nanmin(lat)
lat -= 360. * ((lat - lat0) > 180.)

lon_min, lon_max = np.nanmin(lon), np.nanmax(lon)
lat_min, lat_max = np.nanmin(lat), np.nanmax(lat)

lon_min, lon_max, lat_min, lat_max = \
self._add_pad(lon_min, lon_max, lat_min, lat_max)

# check cycle
if self.lon_cycle:
lon_max = min(lon_max, lon_min + self.lon_cycle)
if self.lat_cycle: # pragma: no cover
lat_max = min(lat_max, lat_min + self.lat_cycle)

if self.lon_minmax is not None:
min0 = self.lon_minmax[0]
lon_min = max(min0, lon_min)
max0 = self.lon_minmax[1]
lon_max = min(max0, lon_max)

if self.lat_minmax is not None:
min0 = self.lat_minmax[0]
lat_min = max(min0, lat_min)
max0 = self.lat_minmax[1]
lat_max = min(max0, lat_max)

return lon_min, lon_max, lat_min, lat_max


def sgrid(subplot=(1, 1, 1), scaling=None):
# From matplotlib demos:
# https://matplotlib.org/gallery/axisartist/demo_curvelinear_grid.html
Expand All @@ -87,14 +40,14 @@ def sgrid(subplot=(1, 1, 1), scaling=None):
# system in degrees
tr = Affine2D().scale(np.pi/180., 1.) + PolarAxes.PolarTransform()

# polar projection, which involves cycle, and also has limits in
# its coordinates, needs a special method to find the extremes
# (min, max of the coordinate within the view).
# The s-plane grid spans the fixed longitude interval 90-270 degrees.
# Disable cycle unwrapping at the 180-degree boundary and use lon_minmax
# to clip the grid to the left half-plane.

# 20, 20 : number of sampling points along x, y direction
sampling_points = 20
extreme_finder = ModifiedExtremeFinderCycle(
sampling_points, sampling_points, lon_cycle=360, lat_cycle=None,
extreme_finder = angle_helper.ExtremeFinderCycle(
sampling_points, sampling_points, lon_cycle=None, lat_cycle=None,
lon_minmax=(90, 270), lat_minmax=(0, np.inf),)

grid_locator1 = angle_helper.LocatorDMS(15)
Expand Down
14 changes: 14 additions & 0 deletions control/tests/grid_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import numpy as np
import matplotlib.pyplot as plt

from control.grid import sgrid


def test_sgrid_does_not_unwrap_longitude(mplcleanup):
ax, fig = sgrid()
finder = ax.get_grid_helper().grid_finder.extreme_finder

assert finder.lon_cycle is None
limits = finder(lambda x, y: (x, y), 90, 0, 270.001, 1)
np.testing.assert_allclose(limits, (90, 270, 0, 1.05))
plt.close(fig)