/usr/lib/python2.7/dist-packages/rasterio/plot.py is in python-rasterio 0.36.0-2build5.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 | """Implementations of various common operations.
Including `show()` for displaying an array or with matplotlib.
Most can handle a numpy array or `rasterio.Band()`.
Primarily supports `$ rio insp`.
"""
from __future__ import absolute_import
import logging
import warnings
import numpy as np
import rasterio
from rasterio._io import RasterReader
from rasterio.compat import zip_longest
logger = logging.getLogger(__name__)
def get_plt():
"""import matplotlib.pyplot
raise import error if matplotlib is not installed
"""
try:
import matplotlib.pyplot as plt
return plt
except (ImportError, RuntimeError): # pragma: no cover
msg = "Could not import matplotlib\n"
msg += "matplotlib required for plotting functions"
raise ImportError(msg)
def show(source, with_bounds=True, contour=False, contour_label_kws=None,
ax=None, title=None, **kwargs):
"""Display a raster or raster band using matplotlib.
Parameters
----------
source : array-like in raster axis order,
or (raster dataset, bidx) tuple,
or raster dataset,
If the tuple (raster dataset, bidx),
selects band `bidx` from raster. If raster dataset display the rgb image
as defined in the colorinterp metadata, or default to first band.
with_bounds : bool (opt)
Whether to change the image extent to the spatial bounds of the image,
rather than pixel coordinates. Only works when source is
(raster dataset, bidx) or raster dataset.
contour : bool (opt)
Whether to plot the raster data as contours
contour_label_kws : dictionary (opt)
Keyword arguments for labeling the contours,
empty dictionary for no labels.
ax : matplotlib axis (opt)
Axis to plot on, otherwise uses current axis.
title : str, optional
Title for the figure.
**kwargs : key, value pairings optional
These will be passed to the matplotlib imshow or contour method
depending on contour argument.
See full lists at:
http://matplotlib.org/api/axes_api.html?highlight=imshow#matplotlib.axes.Axes.imshow
or
http://matplotlib.org/api/axes_api.html?highlight=imshow#matplotlib.axes.Axes.contour
Returns
-------
ax : matplotlib Axes
Axes with plot.
"""
plt = get_plt()
if isinstance(source, tuple):
arr = source[0].read(source[1])
if with_bounds:
kwargs['extent'] = plotting_extent(source[0])
elif isinstance(source, RasterReader):
if source.count == 1:
arr = source.read(1, masked=True)
else:
try:
source_colorinterp = {source.colorinterp(n): n for n in source.indexes}
colorinterp = rasterio.enums.ColorInterp
rgb_indexes = [source_colorinterp[ci] for ci in
(colorinterp.red, colorinterp.green, colorinterp.blue)]
arr = source.read(rgb_indexes, masked=True)
arr = reshape_as_image(arr)
if with_bounds:
kwargs['extent'] = plotting_extent(source)
except KeyError:
arr = source.read(1, masked=True)
else:
# The source is a numpy array reshape it to image if it has 3+ bands
source = np.ma.squeeze(source)
if len(source.shape) >= 3:
arr = reshape_as_image(source)
else:
arr = source
show = False
if not ax:
show = True
ax = plt.gca()
if contour:
if 'cmap' not in kwargs:
kwargs['colors'] = kwargs.get('colors', 'red')
kwargs['linewidths'] = kwargs.get('linewidths', 1.5)
kwargs['alpha'] = kwargs.get('alpha', 0.8)
C = ax.contour(arr, origin='upper', **kwargs)
if contour_label_kws is None:
# no explicit label kws passed use defaults
contour_label_kws = dict(fontsize=8,
inline=True)
if contour_label_kws:
ax.clabel(C, **contour_label_kws)
else:
ax.imshow(arr, **kwargs)
if title:
ax.set_title(title, fontweight='bold')
if show:
plt.show()
return ax
def plotting_extent(source):
"""Returns an extent in the format needed
for matplotlib's imshow (left, right, bottom, top)
instead of rasterio's bounds (left, bottom, top, right)
Parameters
----------
source : raster dataset
"""
extent = (source.bounds.left, source.bounds.right,
source.bounds.bottom, source.bounds.top)
return extent
def reshape_as_image(arr):
"""Returns the source array reshaped into the order
expected by image processing and visualization software
(matplotlib, scikit-image, etc)
by swapping the axes order from (bands, rows, columns)
to (rows, columns, bands)
Parameters
----------
source : array-like in a of format (bands, rows, columns)
"""
# swap the axes order from (bands, rows, columns) to (rows, columns, bands)
im = np.ma.transpose(arr, [1,2,0])
return im
def reshape_as_raster(arr):
"""Returns the array in a raster order
by swapping the axes order from (rows, columns, bands)
to (bands, rows, columns)
Parameters
----------
arr : array-like in the image form of (rows, columns, bands)
"""
# swap the axes order from (rows, columns, bands) to (bands, rows, columns)
im = np.transpose(arr, [2,0,1])
return im
def show_hist(source, bins=10, masked=True, title='Histogram', ax=None, **kwargs):
"""Easily display a histogram with matplotlib.
Parameters
----------
source : np.array or RasterReader, rasterio.Band or tuple(dataset, bidx)
Input data to display. The first three arrays in multi-dimensional
arrays are plotted as red, green, and blue.
bins : int, optional
Compute histogram across N bins.
masked : bool, optional
When working with a `rasterio.Band()` object, specifies if the data
should be masked on read.
title : str, optional
Title for the figure.
ax : matplotlib axes (opt)
The raster will be added to this axes if passed.
**kwargs : optional keyword arguments
These will be passed to the matplotlib hist method. See full list at:
http://matplotlib.org/api/axes_api.html?highlight=imshow#matplotlib.axes.Axes.hist
"""
plt = get_plt()
if isinstance(source, RasterReader):
arr = source.read(masked=masked)
elif isinstance(source, (tuple, rasterio.Band)):
arr = source[0].read(source[1], masked=masked)
else:
arr = source
# The histogram is computed individually for each 'band' in the array
# so we need the overall min/max to constrain the plot
rng = arr.min(), arr.max()
if len(arr.shape) is 2:
arr = np.expand_dims(arr.flatten(), 0).T
colors = ['gold']
else:
arr = arr.reshape(arr.shape[0], -1).T
colors = ['red', 'green', 'blue', 'violet', 'gold', 'saddlebrown']
#The goal is to provide a curated set of colors for working with
# smaller datasets and let matplotlib define additional colors when
# working with larger datasets.
if arr.shape[-1] > len(colors):
n = arr.shape[-1] - len(colors)
colors.extend(np.ndarray.tolist(plt.get_cmap('Accent')(np.linspace(0, 1, n))))
else:
colors = colors[:arr.shape[-1]]
# If a rasterio.Band() is given make sure the proper index is displayed
# in the legend.
if isinstance(source, (tuple, rasterio.Band)):
labels = [str(source[1])]
else:
labels = (str(i + 1) for i in range(len(arr)))
if ax:
show = False
else:
show = True
ax = plt.gca()
fig = ax.get_figure()
ax.hist(arr,
bins=bins,
color=colors,
label=labels,
range=rng,
**kwargs)
ax.legend(loc="upper right")
ax.set_title(title, fontweight='bold')
ax.grid(True)
ax.set_xlabel('DN')
ax.set_ylabel('Frequency')
if show:
plt.show()
|