Skip to content

Commit 4f80a70

Browse files
DOC: Add advanced tutorial "Creating legends" (#3594)
Co-authored-by: Dongdong Tian <seisman.info@gmail.com>
1 parent 8c270a2 commit 4f80a70

File tree

1 file changed

+159
-0
lines changed

1 file changed

+159
-0
lines changed
Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
"""
2+
Creating legends
3+
================
4+
5+
The :meth:`pygmt.Figure.legend` method creates legends, whereby auto-legends as well as
6+
manually created legends are supported.
7+
"""
8+
9+
# %%
10+
import io
11+
12+
import pygmt
13+
14+
# %%
15+
# Create an auto-legend
16+
# ---------------------
17+
#
18+
# An auto-legend can be created for the methods :meth:`pygmt.Figure.plot` and
19+
# :meth:`pygmt.Figure.plot3d`, :meth:`pygmt.Figure.hlines` and
20+
# :meth:`pygmt.Figure.vlines` as well as :meth:`pygmt.Figure.histogram`. Therefore the
21+
# ``label`` parameter has to be specified to state the desired text for the legend entry
22+
# (white spaces are supported). Here, we use :meth:`pygmt.Figure.plot`, exemplary. By
23+
# default, the legend is placed in the Upper Right corner with an offset of 0.1
24+
# centimeters in both x and y directions, and surrounded by a box with a white fill and
25+
# a 1-point thick, black, solid outline. The order of the legend entries (top to bottom)
26+
# is determine by the plotting order. Optionally, to adjust the legend, append different
27+
# modifiers to the string passed to ``label``. For a list of available modifiers see
28+
# :gmt-docs:`gmt.html#l-full`. To create a :doc:`multiple-column legend
29+
# </gallery/embellishments/legend>` **+N** is used with the desired number of columns.
30+
31+
fig = pygmt.Figure()
32+
fig.basemap(region=[-5, 5, -5, 5], projection="X5c", frame=True)
33+
34+
# Plot two data points and one line
35+
fig.plot(x=0, y=0, style="c0.2c", fill="orange", label="orange circle")
36+
fig.plot(x=1, y=0, style="t0.3c", fill="pink", pen="black", label="pink triangle")
37+
fig.plot(x=[-3, 3], y=[-2, -2], pen="darkred", label="darkred line")
38+
39+
# Add a legend based on the explanation text given via the "label" parameter.
40+
fig.legend()
41+
42+
fig.show()
43+
44+
45+
# %%
46+
# Adjust the position
47+
# -------------------
48+
#
49+
# Use the ``position`` parameter to adjust the position of the legend. Add an offset via
50+
# **+o** for the x and y directions. Additionally append **+w** to adjust the width
51+
# of the legend. Note, no box is drawn by default if ``position`` is used.
52+
53+
fig = pygmt.Figure()
54+
fig.basemap(region=[-5, 5, -5, 5], projection="X5c", frame=True)
55+
56+
fig.plot(x=0, y=0, style="c0.25c", fill="orange", label="orange circle")
57+
fig.plot(x=1, y=0, style="t0.3c", fill="pink", pen="black", label="pink triangle")
58+
fig.plot(x=[-3, 3], y=[-2, -2], pen="darkred", label="darkred line")
59+
60+
# Set the reference point to the Top Left corner within (lowercase "j") the bounding box
61+
# of the plot and use offsets of 0.3 and 0.2 centimeters in the x and y directions,
62+
# respectively.
63+
fig.legend(position="jTL+o0.3c/0.2c")
64+
65+
fig.show()
66+
67+
68+
# %%
69+
# Add a box
70+
# ---------
71+
# Use the ``box`` parameter for adjusting the box around the legend. The outline of the
72+
# box can be adjusted by appending **+p**. Append **+g** to fill the legend with a color
73+
# (or pattern) [Default is no fill]. The default of ``position`` is preserved.
74+
75+
fig = pygmt.Figure()
76+
fig.basemap(region=[-5, 5, -5, 5], projection="X5c", frame="rltb+glightgray")
77+
78+
fig.plot(x=0, y=0, style="c0.25c", fill="orange", label="orange circle")
79+
fig.plot(x=1, y=0, style="t0.3c", fill="pink", pen="black", label="pink triangle")
80+
fig.plot(x=[-3, 3], y=[-2, -2], pen="darkred", label="darkred line")
81+
82+
fig.legend(position="jTL+o0.3c/0.2c", box=True)
83+
84+
fig.shift_origin(xshift="w+1c")
85+
fig.basemap(region=[-5, 5, -5, 5], projection="X5c", frame="rltb+glightgray")
86+
87+
fig.plot(x=0, y=0, style="c0.25c", fill="orange", label="orange circle")
88+
fig.plot(x=1, y=0, style="t0.3c", fill="pink", pen="black", label="pink triangle")
89+
fig.plot(x=[-3, 3], y=[-2, -2], pen="darkred", label="darkred line")
90+
91+
# Add a box with a 2-points thick blue, solid outline and a white fill with a
92+
# transparency of 70 percentage ("@30").
93+
fig.legend(position="jTL+o0.3c/0.2c", box="+p2p,blue+gwhite@30")
94+
95+
fig.show()
96+
97+
98+
# %%
99+
# Create a manual legend
100+
# ----------------------
101+
#
102+
# For more complicated legends, users need to prepare a legend specification with
103+
# instructions for the layout of the legend entries. In PyGMT, the legend specification
104+
# can be either an ASCII file or an :class:`io.StringIO` object. Both are passed to the
105+
# ``spec`` parameter of :meth:`pygmt.Figure.legend`. Multiple legend codes are available
106+
# to create complicated legends. In the example below we show an subset; a full
107+
# overview can be found at :gmt-docs:`legend.html#legend-codes`. It's also supported to
108+
# include length scales (for geographic projections), faults, and images as well as to
109+
# add specific lines.
110+
#
111+
# The following example is orientated on the related GMT example at
112+
# :gmt-docs:`legend.html#examples`, but modified to use an :class:`io.StringIO` object.
113+
#
114+
# We start with setting up the :class:`io.StringIO` object.
115+
116+
spec_io = io.StringIO(
117+
"""
118+
G -0.1c
119+
H 24p,Times-Roman My Map Legend
120+
D 0.2c 1p
121+
N 2
122+
V 0 1p
123+
S 0.1c c 0.20c p300/12 0.25p 0.3c This circle is hachured
124+
S 0.1c e 0.20c yellow 0.25p 0.3c This ellipse is yellow
125+
S 0.1c w 0.20c green 0.25p 0.3c This wedge is green
126+
S 0.1c f 0.25c blue 0.25p 0.3c This is a fault
127+
S 0.1c - 0.15c - 0.25p,- 0.3c A contour
128+
S 0.1c v 0.25c magenta 0.5p 0.3c This is a vector
129+
S 0.1c i 0.20c cyan 0.25p 0.3c This inverse triangle is cyan
130+
D 0.2c 1p
131+
V 0 1p
132+
N 1
133+
G 0.1c
134+
M 5 5 600+u+f
135+
G 0.1c
136+
I @SOEST_block4.png 3i CT
137+
G 0.05c
138+
L 9p,Times-Roman R Smith et al., @%5%J. Geophys. Res., 99@%%, 2000
139+
G 0.1c
140+
T Let us just try some simple text that can go on a few lines.
141+
T There is no easy way to predetermine how many lines may be required
142+
T so we may have to adjust the height to get the right size box.
143+
"""
144+
)
145+
146+
# %%
147+
# Now, we can add a legend based on this :class:`io.StringIO` object. For multi-columns
148+
# legends, the width (**+w**) has to be specified via a the ``position`` parameter.
149+
150+
fig = pygmt.Figure()
151+
# Note, that we are now using a Mercator projection
152+
fig.basemap(region=[-5, 5, -5, 5], projection="M10c", frame=True)
153+
154+
# Pass the io.StringIO object to the "spec" parameter
155+
fig.legend(spec=spec_io, position="jMC+w9c", box="+p1p,gray50+ggray95")
156+
157+
fig.show()
158+
159+
# sphinx_gallery_thumbnail_number = 4

0 commit comments

Comments
 (0)