Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit c4a600b

Browse filesBrowse files
authored
Merge pull request #27430 from meeseeksmachine/auto-backport-of-pr-27411-on-v3.8.2-doc
Backport PR #27411 on branch v3.8.2-doc (DOC: multilevel tick example)
2 parents 3655ff8 + c19ea29 commit c4a600b
Copy full SHA for c4a600b

File tree

Expand file treeCollapse file tree

1 file changed

+99
-0
lines changed
Filter options
Expand file treeCollapse file tree

1 file changed

+99
-0
lines changed
+99Lines 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', 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)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.