Skip to content

Commit 7a33e91

Browse files
Meghan Jonesweiji14seismanmichaelgrund
authored andcommitted
Add a tutorial for grdhisteq (GenericMappingTools#1821)
Co-authored-by: Wei Ji <23487320+weiji14@users.noreply.github.com> Co-authored-by: Dongdong Tian <seisman.info@gmail.com> Co-authored-by: Michael Grund <23025878+michaelgrund@users.noreply.github.com>
1 parent 41addf3 commit 7a33e91

File tree

1 file changed

+221
-0
lines changed

1 file changed

+221
-0
lines changed
Lines changed: 221 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,221 @@
1+
"""
2+
Performing grid histogram equalization
3+
--------------------------------------
4+
The :meth:`pygmt.grdhisteq.equalize_grid` function creates a grid using
5+
statistics based on a cumulative distribution function.
6+
"""
7+
# sphinx_gallery_thumbnail_number = 3
8+
9+
import pygmt
10+
11+
###############################################################################
12+
# Load sample data
13+
# ----------------
14+
# Load the sample Earth relief data for a region around Yosemite valley
15+
# and use :meth:`pygmt.grd2xyz` to create a :class:`pandas.Series` with the
16+
# z values.
17+
18+
grid = pygmt.datasets.load_earth_relief(
19+
resolution="03s", region=[-119.825, -119.4, 37.6, 37.825]
20+
)
21+
grid_dist = pygmt.grd2xyz(grid=grid, output_type="pandas")["elevation"]
22+
23+
###############################################################################
24+
# Plot the original digital elevation model and data distribution
25+
# ---------------------------------------------------------------
26+
# For comparison, we will create a map of the original digital elevation
27+
# model and a histogram showing the distribution of elevation data values.
28+
29+
# Create an instance of the Figure class
30+
fig = pygmt.Figure()
31+
# Define figure configuration
32+
pygmt.config(FORMAT_GEO_MAP="ddd.x", MAP_FRAME_TYPE="plain")
33+
# Define the colormap for the figure
34+
pygmt.makecpt(series=[500, 3540], cmap="turku")
35+
# Setup subplots with two panels
36+
with fig.subplot(
37+
nrows=1, ncols=2, figsize=("13.5c", "4c"), title="Digital Elevation Model"
38+
):
39+
# Plot the original digital elevation model in the first panel
40+
with fig.set_panel(panel=0):
41+
fig.grdimage(grid=grid, projection="M?", frame="WSne", cmap=True)
42+
# Plot a histogram showing the z-value distribution in the original digital
43+
# elevation model
44+
with fig.set_panel(panel=1):
45+
fig.histogram(
46+
data=grid_dist,
47+
projection="X?",
48+
region=[500, 3600, 0, 20],
49+
series=[500, 3600, 100],
50+
frame=["wnSE", "xaf+lElevation (m)", "yaf+lCounts"],
51+
cmap=True,
52+
histtype=1,
53+
pen="1p,black",
54+
)
55+
fig.colorbar(position="JMR+o1.5c/0c+w3c/0.3c", frame=True)
56+
fig.show()
57+
58+
###############################################################################
59+
# Equalize grid based on a linear distribution
60+
# --------------------------------------------
61+
# The :meth:`pygmt.grdhisteq.equalize_grid` method creates a new grid with the
62+
# z-values representing the position of the original z-values in a given
63+
# cumulative distribution. By default, it computes the position in a linear
64+
# distribution. Here, we equalize the grid into nine divisions based on a
65+
# linear distribution and produce a :class:`pandas.Series` with the z-values
66+
# for the new grid.
67+
68+
divisions = 9
69+
linear = pygmt.grdhisteq.equalize_grid(grid=grid, divisions=divisions)
70+
linear_dist = pygmt.grd2xyz(grid=linear, output_type="pandas")["z"]
71+
72+
###############################################################################
73+
# Calculate the bins used for data transformation
74+
# -----------------------------------------------
75+
# The :meth:`pygmt.grdhisteq.compute_bins` method reports statistics about the
76+
# grid equalization. Here, we report the bins that would linearly divide the
77+
# original data into 9 divisions with equal area. In our new grid produced by
78+
# :meth:`pygmt.grdhisteq.equalize_grid`, all the grid cells with values between
79+
# ``start`` and ``stop`` of ``bin_id=0`` are assigned the value 0, all grid
80+
# cells with values between ``start`` and ``stop`` of ``bin_id=1`` are assigned
81+
# the value 1, and so on.
82+
83+
pygmt.grdhisteq.compute_bins(grid=grid, divisions=divisions)
84+
85+
###############################################################################
86+
# Plot the equally distributed data
87+
# ---------------------------------------------------------------
88+
# Here we create a map showing the grid that has been transformed to
89+
# have a linear distribution with nine divisions and a histogram of the data
90+
# values.
91+
92+
# Create an instance of the Figure class
93+
fig = pygmt.Figure()
94+
# Define figure configuration
95+
pygmt.config(FORMAT_GEO_MAP="ddd.x", MAP_FRAME_TYPE="plain")
96+
# Define the colormap for the figure
97+
pygmt.makecpt(series=[0, divisions, 1], cmap="lajolla")
98+
# Setup subplots with two panels
99+
with fig.subplot(
100+
nrows=1, ncols=2, figsize=("13.5c", "4c"), title="Linear distribution"
101+
):
102+
# Plot the grid with a linear distribution in the first panel
103+
with fig.set_panel(panel=0):
104+
fig.grdimage(grid=linear, projection="M?", frame="WSne", cmap=True)
105+
# Plot a histogram showing the linear z-value distribution
106+
with fig.set_panel(panel=1):
107+
fig.histogram(
108+
data=linear_dist,
109+
projection="X?",
110+
region=[0, divisions, 0, 40],
111+
series=[0, divisions, 1],
112+
frame=["wnSE", "xaf+lElevation (m)", "yaf+lCounts"],
113+
cmap=True,
114+
histtype=1,
115+
pen="1p,black",
116+
)
117+
fig.colorbar(position="JMR+o1.5c/0c+w3c/0.3c", frame=True)
118+
fig.show()
119+
120+
###############################################################################
121+
# Transform grid based on a normal distribution
122+
# ---------------------------------------------
123+
# The ``gaussian`` parameter of :meth:`pygmt.grdhisteq.equalize_grid` can be
124+
# used to transform the z-values relative to their position in a normal
125+
# distribution rather than a linear distribution. In this case, the output
126+
# data are continuous rather than discrete.
127+
128+
normal = pygmt.grdhisteq.equalize_grid(grid=grid, gaussian=True)
129+
normal_dist = pygmt.grd2xyz(grid=normal, output_type="pandas")["z"]
130+
131+
###############################################################################
132+
# Plot the normally distributed data
133+
# ----------------------------------
134+
# Here we create a map showing the grid that has been transformed to have
135+
# a normal distribution and a histogram of the data values.
136+
137+
# Create an instance of the Figure class
138+
fig = pygmt.Figure()
139+
# Define figure configuration
140+
pygmt.config(FORMAT_GEO_MAP="ddd.x", MAP_FRAME_TYPE="plain")
141+
# Define the colormap for the figure
142+
pygmt.makecpt(series=[-4.5, 4.5], cmap="vik")
143+
# Setup subplots with two panels
144+
with fig.subplot(
145+
nrows=1, ncols=2, figsize=("13.5c", "4c"), title="Normal distribution"
146+
):
147+
# Plot the grid with a normal distribution in the first panel
148+
with fig.set_panel(panel=0):
149+
fig.grdimage(grid=normal, projection="M?", frame="WSne", cmap=True)
150+
# Plot a histogram showing the normal z-value distribution
151+
with fig.set_panel(panel=1):
152+
fig.histogram(
153+
data=normal_dist,
154+
projection="X?",
155+
region=[-4.5, 4.5, 0, 20],
156+
series=[-4.5, 4.5, 0.2],
157+
frame=["wnSE", "xaf+lElevation (m)", "yaf+lCounts"],
158+
cmap=True,
159+
histtype=1,
160+
pen="1p,black",
161+
)
162+
fig.colorbar(position="JMR+o1.5c/0c+w3c/0.3c", frame=True)
163+
fig.show()
164+
165+
###############################################################################
166+
# Equalize grid based on a quadratic distribution
167+
# -----------------------------------------------
168+
# The ``quadratic`` parameter of :meth:`pygmt.grdhisteq.equalize_grid` can be
169+
# used to transform the z-values relative to their position in a quadratic
170+
# distribution rather than a linear distribution. Here, we equalize the grid
171+
# into nine divisions based on a quadratic distribution and produce a
172+
# :class:`pandas.Series` with the z-values for the new grid.
173+
174+
quadratic = pygmt.grdhisteq.equalize_grid(
175+
grid=grid, quadratic=True, divisions=divisions
176+
)
177+
quadratic_dist = pygmt.grd2xyz(grid=quadratic, output_type="pandas")["z"]
178+
179+
###############################################################################
180+
# Calculate the bins used for data transformation
181+
# -----------------------------------------------
182+
# We can also use the ``quadratic`` parameter of
183+
# :meth:`pygmt.grdhisteq.compute_bins` to report the bins used for dividing
184+
# the grid into 9 divisions based on their position in a quadratic
185+
# distribution.
186+
187+
pygmt.grdhisteq.compute_bins(grid=grid, divisions=divisions, quadratic=True)
188+
189+
###############################################################################
190+
# Plot the quadratic distribution of data
191+
# ---------------------------------------
192+
# Here we create a map showing the grid that has been transformed to have
193+
# a quadratic distribution and a histogram of the data values.
194+
195+
# Create an instance of the Figure class
196+
fig = pygmt.Figure()
197+
# Define figure configuration
198+
pygmt.config(FORMAT_GEO_MAP="ddd.x", MAP_FRAME_TYPE="plain")
199+
# Define the colormap for the figure
200+
pygmt.makecpt(series=[0, divisions, 1], cmap="lajolla")
201+
# Setup subplots with two panels
202+
with fig.subplot(
203+
nrows=1, ncols=2, figsize=("13.5c", "4c"), title="Quadratic distribution"
204+
):
205+
# Plot the grid with a quadratic distribution in the first panel
206+
with fig.set_panel(panel=0):
207+
fig.grdimage(grid=quadratic, projection="M?", frame="WSne", cmap=True)
208+
# Plot a histogram showing the quadratic z-value distribution
209+
with fig.set_panel(panel=1):
210+
fig.histogram(
211+
data=quadratic_dist,
212+
projection="X?",
213+
region=[0, divisions, 0, 40],
214+
series=[0, divisions, 1],
215+
frame=["wnSE", "xaf+lElevation (m)", "yaf+lCounts"],
216+
cmap=True,
217+
histtype=1,
218+
pen="1p,black",
219+
)
220+
fig.colorbar(position="JMR+o1.5c/0c+w3c/0.3c", frame=True)
221+
fig.show()

0 commit comments

Comments
 (0)