Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Matplotlib semi-log plot: minor tick marks are gone when range is large

When making a semi-log plot (y is log), the minor tick marks (8 in a decade) on the y axis appear automatically, but it seems that when the axis range exceeds 10**10, they disappear. I tried many ways to force them back in, but to no avail. It might be that they go away for large ranges to avoid overcrowding, but one should have a choice?

like image 742
Chuck Avatar asked May 19 '17 20:05

Chuck


People also ask

How do I get rid of minor ticks in matplotlib?

Matplotlib removes both labels and ticks by using xticks([]) and yticks([]) By using the method xticks() and yticks() you can disable the ticks and tick labels from both the x-axis and y-axis.

How do I enable minor ticks in matplotlib?

MatPlotLib with Python Create a figure and a set of subplots. Plot x and y data points using plot() method. To locate minor ticks, use set_minor_locator() method. To show the minor ticks, use grid(which='minor').

How do I increase the number of tick marks in matplotlib?

Method 1: Using xticks() and yticks() xticks() and yticks() is the function that lets us customize the x ticks and y ticks by giving the values as a list, and we can also give labels for the ticks, matters, and as **kwargs we can apply text effects on the tick labels.

How do I show all ticks in matplotlib?

Argument direction (in) helps to put ticks inside the axes, and axis (both), parameters to be applied on both the axes. To show the figure, use plt. show() method.


2 Answers

solution for matplotlib >= 2.0.2

Let's consider the following example

enter image description here

which is produced by this code:

import matplotlib.pyplot as plt import matplotlib.ticker import numpy as np  y = np.arange(12) x = 10.0**y  fig, ax=plt.subplots() ax.plot(x,y) ax.set_xscale("log") plt.show() 

The minor ticklabels are indeed gone and usual ways to show them (like plt.tick_params(axis='x', which='minor')) fail.

The first step would then be to show all powers of 10 on the axis,

locmaj = matplotlib.ticker.LogLocator(base=10,numticks=12)  ax.xaxis.set_major_locator(locmaj) 

enter image description here

where the trick is to set numticks to a number equal or larger the number of ticks (i.e. 12 or higher in this case).

Then, we can add minor ticklabels as

locmin = matplotlib.ticker.LogLocator(base=10.0,subs=(0.2,0.4,0.6,0.8),numticks=12) ax.xaxis.set_minor_locator(locmin) ax.xaxis.set_minor_formatter(matplotlib.ticker.NullFormatter()) 

enter image description here

Note that I restricted this to include 4 minor ticks per decade (using 8 is equally possible but in this example would overcrowd the axes). Also note that numticks is again (quite unintuitively) 12 or larger.

Finally we need to use a NullFormatter() for the minor ticks, in order not to have any ticklabels appear for them.

solution for matplotlib 2.0.0

The following works in matplotlib 2.0.0 or below, but it does not work in matplotlib 2.0.2.

Let's consider the following example

enter image description here

which is produced by this code:

import matplotlib.pyplot as plt import matplotlib.ticker import numpy as np  y = np.arange(12) x = 10.0**y  fig, ax=plt.subplots() ax.plot(x,y) ax.set_xscale("log") plt.show() 

The minor ticklabels are indeed gone and usual ways to show them (like plt.tick_params(axis='x', which='minor')) fail.

The first step would then be to show all powers of 10 on the axis,

locmaj = matplotlib.ticker.LogLocator(base=10.0, subs=(0.1,1.0, )) ax.xaxis.set_major_locator(locmaj) 

enter image description here

Then, we can add minor ticklabels as

locmin = matplotlib.ticker.LogLocator(base=10.0, subs=(0.1,0.2,0.4,0.6,0.8,1,2,4,6,8,10 ))  ax.xaxis.set_minor_locator(locmin) ax.xaxis.set_minor_formatter(matplotlib.ticker.NullFormatter()) 

enter image description here

Note that I restricted this to include 4 minor ticks per decade (using 8 is equally possible but in this example would overcrowd the axes). Also note - and that may be the key here - that the subs argument, which gives the multiples of integer powers of the base at which to place ticks (see documentation), is given a list ranging over two decades instead of one.

Finally we need to use a NullFormatter() for the minor ticks, in order not to have any ticklabels appear for them.

like image 144
ImportanceOfBeingErnest Avatar answered Sep 18 '22 14:09

ImportanceOfBeingErnest


Major ticks with empty labels will generate ticks but no labels.

ax.set_yticks([1.E-6,1.E-5,1.E-4,1.E-3,1.E-2,1.E-1,1.E0,1.E1,1.E2,1.E3,1.E4,1.E5,])  ax.set_yticklabels(['$10^{-6}$','','','$10^{-3}$','','','$1$','','','$10^{3}$','','']) 

Tick Labels

like image 21
Ahsan Zeb Avatar answered Sep 20 '22 14:09

Ahsan Zeb