80

It seems that the set_xticks is not working in log scale:

from matplotlib import pyplot as plt
fig1, ax1 = plt.subplots()
ax1.plot([10, 100, 1000], [1,2,3])
ax1.set_xscale('log')
ax1.set_xticks([20, 200, 500])
plt.show()

is it possible?

MERose
  • 3,421
  • 7
  • 48
  • 73
Ruggero Turra
  • 15,540
  • 14
  • 84
  • 131

4 Answers4

98
import matplotlib
from matplotlib import pyplot as plt
fig1, ax1 = plt.subplots()
ax1.plot([10, 100, 1000], [1,2,3])
ax1.set_xscale('log')
ax1.set_xticks([20, 200, 500])
ax1.get_xaxis().set_major_formatter(matplotlib.ticker.ScalarFormatter())

or

ax1.get_xaxis().get_major_formatter().labelOnlyBase = False
plt.show()

resulting plot

asmeurer
  • 80,291
  • 25
  • 162
  • 229
tacaswell
  • 79,602
  • 19
  • 200
  • 189
  • 13
    Hi, Could you add some explanation as well as a plot of what this outcome looks like? – Joel Jan 07 '16 at 01:12
  • the second option will keep the logarithmic notation in the ticks, ie 20 is going to be 10^1.3 – grasshopper Sep 01 '16 at 17:07
  • This is fine if the labels match their numeric value, but what if you want them to be some other strings? – asmeurer Mar 20 '17 at 21:08
  • I am a big fan of http://matplotlib.org/api/ticker_api.html?highlight=funcformatter#matplotlib.ticker.FuncFormatter which lets you wring a function mapping value -> string. Else use http://matplotlib.org/api/ticker_api.html?highlight=funcformatter#matplotlib.ticker.FixedFormatter + http://matplotlib.org/api/ticker_api.html?highlight=funcformatter#matplotlib.ticker.FixedLocator – tacaswell Mar 20 '17 at 22:47
  • 3
    @tacaswell: The exponential notation `3x10^1` etc. still remains! How do I remove it ? – Srivatsan Jan 16 '18 at 02:21
  • You probably have to turn off the minor formatter as well. – tacaswell Jan 17 '18 at 18:08
  • @tacaswell The 2nd is exactly what I need, but it does not work. I used `set_xticks` to designate what I need, but only the base-conforming ones were displayed, even though the others became 'major' ticks. – physkets Apr 14 '20 at 08:49
20

I'm going to add a few plots and show how to remove the minor ticks:

The OP:

from matplotlib import pyplot as plt

fig1, ax1 = plt.subplots()
ax1.plot([10, 100, 1000], [1,2,3])
ax1.set_xscale('log')
ax1.set_xticks([20, 300, 500])
plt.show()

enter image description here

To add some specific ticks, as tcaswell pointed out, you can use matplotlib.ticker.ScalarFormatter:

from matplotlib import pyplot as plt
import matplotlib.ticker

fig1, ax1 = plt.subplots()
ax1.plot([10, 100, 1000], [1,2,3])
ax1.set_xscale('log')
ax1.set_xticks([20, 300, 500])
ax1.get_xaxis().set_major_formatter(matplotlib.ticker.ScalarFormatter())
plt.show()

enter image description here

To remove the minor ticks, you can use matplotlib.rcParams['xtick.minor.size']:

from matplotlib import pyplot as plt
import matplotlib.ticker

matplotlib.rcParams['xtick.minor.size'] = 0
matplotlib.rcParams['xtick.minor.width'] = 0

fig1, ax1 = plt.subplots()
ax1.plot([10, 100, 1000], [1,2,3])
ax1.set_xscale('log')
ax1.set_xticks([20, 300, 500])
ax1.get_xaxis().set_major_formatter(matplotlib.ticker.ScalarFormatter())

plt.show()

enter image description here

You could use instead ax1.get_xaxis().set_tick_params, it has the same effect (but only modifies the current axis, not all future figures unlike matplotlib.rcParams):

from matplotlib import pyplot as plt
import matplotlib.ticker

fig1, ax1 = plt.subplots()
ax1.plot([10, 100, 1000], [1,2,3])
ax1.set_xscale('log')
ax1.set_xticks([20, 300, 500])
ax1.get_xaxis().set_major_formatter(matplotlib.ticker.ScalarFormatter())

ax1.get_xaxis().set_tick_params(which='minor', size=0)
ax1.get_xaxis().set_tick_params(which='minor', width=0) 

plt.show()

enter image description here

Community
  • 1
  • 1
Franck Dernoncourt
  • 69,497
  • 68
  • 312
  • 474
2

Would be better to use np.geomspace as xticks

ax = sns.histplot(arr, log_scale=True)
ax.xaxis.set_major_formatter(matplotlib.ticker.ScalarFormatter())
ax.set_xticks( np.geomspace(1, 1500 ,15).round() )

enter image description here

Mithril
  • 11,666
  • 17
  • 90
  • 135
1
from matplotlib.ticker import ScalarFormatter, NullFormatter
for axis in [ax.xaxis]:
    axis.set_major_formatter(ScalarFormatter())
    axis.set_minor_formatter(NullFormatter())

This removes the exponential notation

PyariBilli
  • 439
  • 1
  • 5
  • 17