-
-
Notifications
You must be signed in to change notification settings - Fork 7.9k
DOC: multilevel tick example #27411
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
+99
−0
Merged
DOC: multilevel tick example #27411
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
""" | ||
========================= | ||
Multilevel (nested) ticks | ||
========================= | ||
|
||
Sometimes we want another level of tick labels on an axis, perhaps to indicate | ||
a grouping of the ticks. | ||
|
||
Matplotlib does not provide an automated way to do this, but it is relatively | ||
straightforward to annotate below the main axis. | ||
|
||
These examples use `.Axes.secondary_xaxis`, which is one approach. It has the | ||
advantage that we can use Matplotlib Locators and Formatters on the axis that | ||
does the grouping if we want. | ||
|
||
This first example creates a secondary xaxis and manually adds the ticks and | ||
labels using `.Axes.set_xticks`. Note that the tick labels have a newline | ||
(e.g. ``"\nOughts"``) at the beginning of them to put the second-level tick | ||
labels below the main tick labels. | ||
""" | ||
|
||
import matplotlib.pyplot as plt | ||
import numpy as np | ||
|
||
import matplotlib.dates as mdates | ||
|
||
rng = np.random.default_rng(19680801) | ||
|
||
fig, ax = plt.subplots(layout='constrained', figsize=(4, 4)) | ||
|
||
ax.plot(np.arange(30)) | ||
|
||
sec = ax.secondary_xaxis(location=0) | ||
sec.set_xticks([5, 15, 25], labels=['\nOughts', '\nTeens', '\nTwenties']) | ||
|
||
# %% | ||
# This second example adds a second level of annotation to a categorical axis. | ||
# Here we need to note that each animal (category) is assigned an integer, so | ||
# ``cats`` is at x=0, ``dogs`` at x=1 etc. Then we place the ticks on the | ||
# second level on an x that is at the middle of the animal class we are trying | ||
# to delineate. | ||
# | ||
# This example also adds tick marks between the classes by adding a second | ||
# secondary xaxis, and placing long, wide ticks at the boundaries between the | ||
# animal classes. | ||
|
||
fig, ax = plt.subplots(layout='constrained', figsize=(7, 4)) | ||
|
||
ax.plot(['cats', 'dogs', 'pigs', 'snakes', 'lizards', 'chickens', | ||
'eagles', 'herons', 'buzzards'], | ||
rng.normal(size=9), 'o') | ||
|
||
# label the classes: | ||
sec = ax.secondary_xaxis(location=0) | ||
sec.set_xticks([1, 3.5, 6.5], labels=['\n\nMammals', '\n\nReptiles', '\n\nBirds']) | ||
sec.tick_params('x', length=0) | ||
|
||
# lines between the classes: | ||
sec2 = ax.secondary_xaxis(location=0) | ||
sec2.set_xticks([-0.5, 2.5, 4.5, 8.5], labels=[]) | ||
sec2.tick_params('x', length=40, width=1.5) | ||
ax.set_xlim(-0.6, 8.6) | ||
|
||
# %% | ||
# Dates are another common place where we may want to have a second level of | ||
# tick labels. In this last example, we take advantage of the ability to add | ||
# an automatic locator and formatter to the secondary xaxis, which means we do | ||
# not need to set the ticks manually. | ||
# | ||
# This example also differs from the above, in that we placed it at a location | ||
# below the main axes ``location=-0.075`` and then we hide the spine by setting | ||
# the line width to zero. That means that our formatter no longer needs the | ||
# carriage returns of the previous two examples. | ||
|
||
fig, ax = plt.subplots(layout='constrained', figsize=(7, 4)) | ||
|
||
time = np.arange(np.datetime64('2020-01-01'), np.datetime64('2020-03-31'), | ||
np.timedelta64(1, 'D')) | ||
|
||
ax.plot(time, rng.random(size=len(time))) | ||
|
||
# just format the days: | ||
ax.xaxis.set_major_formatter(mdates.DateFormatter('%d')) | ||
|
||
# label the months: | ||
sec = ax.secondary_xaxis(location=-0.075) | ||
sec.xaxis.set_major_locator(mdates.MonthLocator(bymonthday=1)) | ||
|
||
# note the extra spaces in the label to align the month label inside the month. | ||
# Note that this could have been done by changing ``bymonthday`` above as well: | ||
sec.xaxis.set_major_formatter(mdates.DateFormatter(' %b')) | ||
sec.tick_params('x', length=0) | ||
sec.spines['bottom'].set_linewidth(0) | ||
|
||
# label the xaxis, but note for this to look good, it needs to be on the | ||
# secondary xaxis. | ||
sec.set_xlabel('Dates (2020)') | ||
|
||
plt.show() |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assume you add the spaces before the
%b
to improve the alignment with the tick. I just spent longer than I care to admit trying to figure out a way to set the horizontal alignment of the labels, and now I think I understand why you want to overhaulAxis
!For the record, this works, but I'm not sure it would be an improvement.
Is it worth a comment to explain the spaces though?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it's all pretty annoying. And of course that alignment only holds for ticks that presently exist - if you pan off to right or left the new ticks won't get the alignment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
aI think lighter lift to improve this would be to add alignment to
tick_params
#20644