8000 DOC: multilevel tick example (#27411) · matplotlib/matplotlib@d8e272f · GitHub
[go: up one dir, main page]

Skip to content

Commit d8e272f

Browse files
jklymakrcomer
andauthored
DOC: multilevel tick example (#27411)
* DOC: multilevel tick example * Update galleries/examples/ticks/multilevel_ticks.py fix typo Co-authored-by: Ruth Comer <10599679+rcomer@users.noreply.github.com> --------- Co-authored-by: Ruth Comer <10599679+rcomer@users.noreply.github.com>
1 parent 17d8bf0 commit d8e272f

File tree

1 file changed

+99
-0
lines changed

1 file changed

+99
-0
lines changed
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
"""
2+
=========================
3+
Multilevel (nested) ticks
4+
=========================
5+
6+
Sometimes we want another level of tick labels on an axis, perhaps to indicate
7+
a grouping of the ticks.
8+
9+
Matplotlib does not provide an automated way to do this, but it is relatively
10+
straightforward to annotate below the main axis.
11+
12+
These examples use `.Axes.secondary_xaxis`, which is one approach. It has the
13+
advantage that we can use Matplotlib Locators and Formatters on the axis that
14+
does the grouping if we want.
15+
16+
This first example creates a secondary xaxis and manually adds the ticks and
17+
labels using `.Axes.set_xticks`. Note that the tick labels have a newline
18+
(e.g. ``"\nOughts"``) at the beginning of them to put the second-level tick
19+
labels below the main tick labels.
20+
"""
21+
22+
import matplotlib.pyplot as plt
23+
import numpy as np
24+
25+
import matplotlib.dates as mdates
26+
27+
rng = np.random.default_rng(19680801)
28+
29+
fig, ax = plt.subplots(layout='constrained', figsize=(4, 4))
30+
31+
ax.plot(np.arange(30))
32+
33+
sec = ax.secondary_xaxis(location=0)
34+
sec.set_xticks([5, 15, 25], labels=['\nOughts', '\nTeens', '\nTwenties'])
35+
36+
# %%
37+
# This second example adds a second level of annotation to a categorical axis.
38+
# Here we need to note that each animal (category) is assigned an integer, so
39+
# ``cats`` is at x=0, ``dogs`` at x=1 etc. Then we place the ticks on the
40+
# second level on an x that is at the middle of the animal class we are trying
41+
# to delineate.
42+
#
43+
# This example also adds tick marks between the classes by adding a second
44+
# secondary xaxis, and placing long, wide ticks at the boundaries between the
45+
# animal classes.
46+
47+
fig, ax = plt.subplots(layout='constrained', figsize=(7, 4))
48+
49+
ax.plot(['cats', 'dogs', 'pigs', 'snakes', 'lizards', 'chickens',
50+
'eagles', 'herons', 'buzzards'],
51+
rng.normal(size=9), 'o')
52+
53+
# label the classes:
54+
sec = ax.secondary_xaxis(location=0)
55+
sec.set_xticks([1, 3.5, 6.5], labels=['\n\nMammals', '\n\nReptiles', '\n\nBirds'])
56+
sec.tick_params('x' 8000 , length=0)
57+
58+
# lines between the classes:
59+
sec2 = ax.secondary_xaxis(location=0)
60+
sec2.set_xticks([-0.5, 2.5, 4.5, 8.5], labels=[])
61+
sec2.tick_params('x', length=40, width=1.5)
62+
ax.set_xlim(-0.6, 8.6)
63+
64+
# %%
65+
# Dates are another common place where we may want to have a second level of
66+
# tick labels. In this last example, we take advantage of the ability to add
67+
# an automatic locator and formatter to the secondary xaxis, which means we do
68+
# not need to set the ticks manually.
69+
#
70+
# This example also differs from the above, in that we placed it at a location
71+
# below the main axes ``location=-0.075`` and then we hide the spine by setting
72+
# the line width to zero. That means that our formatter no longer needs the
73+
# carriage returns of the previous two examples.
74+
75+
fig, ax = plt.subplots(layout='constrained', figsize=(7, 4))
76+
77+
time = np.arange(np.datetime64('2020-01-01'), np.datetime64('2020-03-31'),
78+
np.timedelta64(1, 'D'))
79+
80+
ax.plot(time, rng.random(size=len(time)))
81+
82+
# just format the days:
83+
ax.xaxis.set_major_formatter(mdates.DateFormatter('%d'))
84+
85+
# label the months:
86+
sec = ax.secondary_xaxis(location=-0.075)
87+
sec.xaxis.set_major_locator(mdates.MonthLocator(bymonthday=1))
88+
89+
# note the extra spaces in the label to align the month label inside the month.
90+
# Note that this could have been done by changing ``bymonthday`` above as well:
91+
sec.xaxis.set_major_formatter(mdates.DateFormatter(' %b'))
92+
sec.tick_params('x', length=0)
93+
sec.spines['bottom'].set_linewidth(0)
94+
95+
# label the xaxis, but note for this to look good, it needs to be on the
96+
# secondary xaxis.
97+
sec.set_xlabel('Dates (2020)')
98+
99+
plt.show()

0 commit comments

Comments
 (0)
0