Skip to content

Commit

Permalink
#99 update Figure.add_latlon_grids and .add_latlon_labels to put grid…
Browse files Browse the repository at this point in the history
…s at predefined locations or evenly
  • Loading branch information
akorosov committed Apr 17, 2015
1 parent adeffa2 commit 7bd4e2f
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 25 deletions.
100 changes: 78 additions & 22 deletions nansat/figure.py
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,7 @@ def add_latlon_grids(self, **kwargs):
Compute step of the grid
Make matrices with binarized lat/lon
Find edge (make line)
Convert to maks
Convert to mask
Add mask to PIL
Parameters
Expand Down Expand Up @@ -422,7 +422,18 @@ def add_latlon_grids(self, **kwargs):
self.apply_mask(mask_array=latI, mask_lut={1: [255, 255, 255]})

def _get_auto_ticks(self, ticks, grid):
''' Automatically create a list of lon or lat ticks
''' Automatically create a list of lon or lat ticks from number of list
Parameters
----------
ticks : int or list
number or location of ticks
grid : ndarray
grid with lon or lat
Returns
-------
ticks : list
location of ticks
'''
gridMin = grid.min()
Expand All @@ -441,20 +452,26 @@ def _get_auto_ticks(self, ticks, grid):

return ticks


def add_latlon_labels(self, **kwargs):
'''Add lat/lon labels along upper and left side
Compute step of lables
Get lat/lon for these labels from latGrid, lonGrid
Print lables to PIL
Print lables to PIL in white
Parameters
----------
Figure__init__() parameters:
Any of Figure__init__() parameters:
latGrid : numpy array
array with values of latitudes
lonGrid : numpy array
latlonLabels : int
array with values of longitudes
lonTicks : int or list
number of lines to draw
or locations of gridlines
latTicks : int or list
number of lines to draw
or locations of gridlines
Modifies
---------
Expand All @@ -463,27 +480,65 @@ def add_latlon_labels(self, **kwargs):
'''
# modify default values
self._set_defaults(kwargs)

# test availability of grids
if (self.latGrid is None or self.lonGrid is None or
self.latlonLabels == 0):
if (self.latGrid is None or self.lonGrid is None):
return

draw = ImageDraw.Draw(self.pilImg)
font = ImageFont.truetype(self.fontFileName, self.fontSize)

# get number of labels; step of lables
llLabels = self.latlonLabels
llShape = self.latGrid.shape
latI = range(0, llShape[0], (llShape[0] / llLabels) - 1)
lonI = range(0, llShape[1], (llShape[1] / llLabels) - 1)
# get lons/lats from first row/column
#lats = self.latGrid[latI, 0]
#lons = self.lonGrid[0, lonI]
for i in range(len(latI)):
lat = self.latGrid[latI[i], 0]
lon = self.lonGrid[0, lonI[i]]
draw.text((0, 10 + latI[i]), '%4.2f' % lat, fill=255, font=font)
draw.text((50 + lonI[i], 0), '%4.2f' % lon, fill=255, font=font)
# get vectors with ticks based on input
latTicks = self._get_auto_ticks(self.latTicks, self.latGrid)
lonTicks = self._get_auto_ticks(self.lonTicks, self.lonGrid)

# get corresponding lons from upper edge and lats from left edge
lonTicksIdx =self._get_tick_index_from_grid(lonTicks, self.lonGrid,
1, self.lonGrid.shape[1])
latTicksIdx =self._get_tick_index_from_grid(latTicks, self.latGrid,
self.lonGrid.shape[0], 1)

# draw lons
lonsOffset = self.lonGrid.shape[1] / len(lonTicksIdx) / 8.
for lonTickIdx in lonTicksIdx:
lon = self.lonGrid[0, lonTickIdx]
draw.text((lonTickIdx+lonsOffset, 0), '%4.2f' % lon,
fill=255, font=font)

# draw lats
latsOffset = self.latGrid.shape[0] / len(latTicksIdx) / 8.
for latTickIdx in latTicksIdx:
lat = self.latGrid[latTickIdx, 0]
draw.text((0, latTickIdx+latsOffset), '%4.2f' % lat,
fill=255, font=font)

def _get_tick_index_from_grid(self, ticks, grid, rows, cols):
''' Get index of pixels from lon/lat grids closest given ticks
Parameters
----------
ticks : int or list
number or location of ticks
grid : ndarray
grid with lon or lat
rows : int
from which rows to return pixels
cols : int
from which cols to return pixels
Returns
-------
ticks : list
index of ticks
'''

newTicksIdx = []
for tick in ticks:
diff = np.abs(grid[:rows, :cols] - tick).flatten()
minDiffIdx = np.nonzero(diff == diff.min())[0][0]
if minDiffIdx > 0 :
newTicksIdx.append(minDiffIdx)
return newTicksIdx

def clim_from_histogram(self, **kwargs):
'''Estimate min and max pixel values from histogram
Expand Down Expand Up @@ -811,7 +866,7 @@ def process(self, **kwargs):
self.create_pilImage(**kwargs)

# add labels with lats/lons
#self.add_latlon_labels()
self.add_latlon_labels()

# add logo
if self.logoFileName is not None:
Expand Down Expand Up @@ -980,3 +1035,4 @@ def _set_defaults(self, idict):
setattr(self, key, [idict[key]])
else:
setattr(self, key, idict[key])

19 changes: 16 additions & 3 deletions nansat/tests/test_figure.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,14 +84,15 @@ def test_add_latlon_grids_number(self):
tmpfilename = os.path.join(ntd.tmp_data_path,
'figure_latlon_grids_number.png')
n = Nansat(self.test_file_gcps)
n.resize(3)
b = n[1]
lon, lat = n.get_geolocation_grids()

f = Figure(b)
f.process(clim='hist', lonGrid=lon,
f.process(cmax=100, lonGrid=lon,
latGrid=lat,
lonTicks=10,
latTicks=10)
lonTicks=7,
latTicks=7)
f.save(tmpfilename)

self.assertEqual(type(f), Figure)
Expand All @@ -115,5 +116,17 @@ def test_add_latlon_grids_list(self):
self.assertEqual(type(f), Figure)
self.assertTrue(os.path.exists(tmpfilename))


def test_get_tick_index_from_grid(self):
''' Should return indeces of pixel closest to ticks '''
n = Nansat(self.test_file_gcps)
lon, lat = n.get_geolocation_grids()

f = Figure(lon)
lonTicksIdx = f._get_tick_index_from_grid([28.5, 29], lon, 1, lon.shape[1])
latTicksIdx = f._get_tick_index_from_grid([71, 71.5], lat, lat.shape[0], 1)
n.logger.error(str(lonTicksIdx))
n.logger.error(str(latTicksIdx))

if __name__ == "__main__":
unittest.main()

0 comments on commit 7bd4e2f

Please sign in to comment.