I have too many ticks on my graph and they are running into each other.
How can I reduce the number of ticks?
For example, I have ticks:
1E-6, 1E-5, 1E-4, ... 1E6, 1E7
And I only want:
1E-5, 1E-3, ... 1E5, 1E7
I've tried playing with the LogLocator
, but I haven't been able to figure this out.
10 Answers 10
Alternatively, if you want to simply set the number of ticks while allowing matplotlib to position them (currently only with MaxNLocator
), there is pyplot.locator_params
,
pyplot.locator_params(nbins=4)
You can specify specific axis in this method as mentioned below, default is both:
# To specify the number of ticks on both or any single axes
pyplot.locator_params(axis='y', nbins=6)
pyplot.locator_params(axis='x', nbins=10)
12 Comments
pyplot.locator_params(axis = 'x', nbins = 4)
(or axis = 'y'
) made the process really straightforward. Thanks @bgamari!numticks
instead of nbins
[0, 1, ..., 99]
and now one sets nticks=10
, then the new sparse labels will be placed ten times as long apart along the axis, i.e. now 1
will sit where 9
was, 2
where 19
was... and 9
where 99
was.To solve the issue of customisation and appearance of the ticks, see the Tick Locators guide on the matplotlib website
ax.xaxis.set_major_locator(plt.MaxNLocator(3))
would set the total number of ticks in the x-axis to 3, and evenly distribute them across the axis.
There is also a nice tutorial about this
6 Comments
ax = df.plot()
pandas.DataFrame
) with datetime index [2019年01月01日, ...2019年11月01日], call ax = df.plot()
, return a figure object . call ax.xaxis.set_major_locator(plt.MaxNLocator(3))
only show first 3 index [2019年01月01日, 2019年01月02日, 2019年01月03日] .df.plot()
often displays the minor_locator
, so you might want to try ax1.xaxis.set_minor_locator(plt.MaxNLocator(3))
. Also remember to substitute the 3
for the number of ticks that you want to display. For pandas timeseries I recommend import matplotlib.dates as mdates
and run ax.xaxis.set_minor_locator(mdates.MonthLocator(interval = 1))
with ax.xaxis.set_minor_formatter(mdates.DateFormatter('%m-%Y'))
set_major_locator(5)
the plotting process is much faster.If somebody still gets this page in search results:
fig, ax = plt.subplots()
plt.plot(...)
every_nth = 4
for n, label in enumerate(ax.xaxis.get_ticklabels()):
if n % every_nth != 0:
label.set_visible(False)
2 Comments
There's a set_ticks()
function for axis objects.
5 Comments
get_xticks()
or get_yticks()
first for the axes object, edit as needed, and then pass the list back to set_ticks()
.set_ticks()
, but I do have set_xticks()
and set_yticks()
. These are attributes of axes objects, not axis. Maybe this has changed during the last couple of years.in case somebody still needs it, and since nothing here really worked for me, i came up with a very simple way that keeps the appearance of the generated plot "as is" while fixing the number of ticks to exactly N:
import numpy as np
import matplotlib.pyplot as plt
f, ax = plt.subplots()
ax.plot(range(100))
ymin, ymax = ax.get_ylim()
ax.set_yticks(np.round(np.linspace(ymin, ymax, N), 2))
2 Comments
ax.set_yticks(np.linspace(int(ymin), int(ymax), N), 2)
The solution @raphael gave is straightforward and quite helpful.
Still, the displayed tick labels will not be values sampled from the original distribution but from the indices of the array returned by np.linspace(ymin, ymax, N)
.
To display N values evenly spaced from your original tick labels, use the set_yticklabels()
method. Here is a snippet for the y axis, with integer labels:
import numpy as np
import matplotlib.pyplot as plt
ax = plt.gca()
ymin, ymax = ax.get_ylim()
custom_ticks = np.linspace(ymin, ymax, N, dtype=int)
ax.set_yticks(custom_ticks)
ax.set_yticklabels(custom_ticks)
Comments
If you need one tick every N=3 ticks :
N = 3 # 1 tick every 3
xticks_pos, xticks_labels = plt.xticks() # get all axis ticks
myticks = [j for i,j in enumerate(xticks_pos) if not i%N] # index of selected ticks
newlabels = [label for i,label in enumerate(xticks_labels) if not i%N]
or with fig,ax = plt.subplots()
:
N = 3 # 1 tick every 3
xticks_pos = ax.get_xticks()
xticks_labels = ax.get_xticklabels()
myticks = [j for i,j in enumerate(xticks_pos) if not i%N] # index of selected ticks
newlabels = [label for i,label in enumerate(xticks_labels) if not i%N]
(obviously you can adjust the offset with (i+offset)%N
).
Note that you can get uneven ticks if you wish, e.g. myticks = [1, 3, 8]
.
Then you can use
plt.gca().set_xticks(myticks) # set new X axis ticks
or if you want to replace labels as well
plt.xticks(myticks, newlabels) # set new X axis ticks and labels
Beware that axis limits must be set after the axis ticks.
Finally, you may wish to draw only an arbitrary set of ticks :
mylabels = ['03/2018', '09/2019', '10/2020']
plt.draw() # needed to populate xticks with actual labels
xticks_pos, xticks_labels = plt.xticks() # get all axis ticks
myticks = [i for i,j in enumerate(xticks_labels) if j.get_text() in mylabels]
plt.xticks(myticks, mylabels)
(assuming mylabels
is ordered ; if it is not, then sort myticks
and reorder it).
2 Comments
myticks = [i for i,j in enumerate(xticks_labels) if j.get_text() in mylabels]
xticks function auto iterates with range function
start_number = 0
end_number = len(data you have)
step_number = how many skips to make from strat to end
rotation = 90 degrees tilt will help with long ticks
plt.xticks(range(start_number,end_number,step_number),rotation=90)
1 Comment
plt.xticks(range(0, df.shape[0], 12),rotation=90)
if you want 10 ticks:
for y axis: ax.set_yticks(ax.get_yticks()[::len(ax.get_yticks())//10])
for x axis: ax.set_xticks(ax.get_xticks()[::len(ax.get_xticks())//10])
this simply gets your ticks and chooses every 10th of the list and sets it back to your ticks. you can change the number of ticks as you wish.
Comments
When a log scale is used the number of major ticks can be fixed with the following command
import matplotlib.pyplot as plt
....
plt.locator_params(numticks=12)
plt.show()
The value set to numticks
determines the number of axis ticks to be displayed.
Credits to @bgamari's post for introducing the locator_params()
function, but the nticks
parameter throws an error when a log scale is used.