Search code examples
pythonmatplotlibplotscalexticks

How to show and increase the size of minor and major ticks on x logscale axis


I am working on the plot of a (logscale,symlog) data. I have difficulties to make appear on x axis (logscale) the minor ticks with a visible height and width.

In x axis, I have values starting from 1e-8 to 1. At the beginning, because of a reason that I don't know, I had only a "2 power 10th" interval, i.e I was getting on the plot of x_axis the values of majors like this :

[1e-8, 1e-6, 1e-4, 1e-2, 1]

I fixed this by doing explicitly :

  # Important otherwise missing ticks
  plt.xticks([1e-8, 1e-7, 1e-6, 1e-5, 1e-4, 1e-3, 1e-2, 1e-1, 1])

So now, I have the following figure :

Missing minor ticks for x axis logscale

As you can see, the minor ticks for each power 10 are missing and I don't know to make them display, even there is not a lot of space between each 10 power.

Here's the code I am using to generate this figure :

# Modules import
import sys
import numpy as np
import scipy.integrate as pyint
import os
from os import path
import glob
import scipy
import re
import shutil
import matplotlib.pyplot as plt 
from matplotlib import ticker

# Initialize figure
fig = plt.figure(num=None, figsize=(12, 12), facecolor='w', edgecolor='k')
fig.patch.set_facecolor('white')
fig.patch.set_alpha(1)

# Control on graphic
ax = plt.gca()

# Increase space between x-axis and x-label
ax.tick_params(axis = 'x', which = 'major', pad = 15)

# Lebels on axis
plt.xlabel('Step $\Omega_{m}$', fontsize = 20)
plt.ylabel('$C_{\ell}^{\'}$($\Omega_{m}$) relative', fontsize = 20)
plt.xticks(fontsize = 20)
plt.yticks(fontsize = 20)
plt.xscale('log')
plt.grid()

# Important otherwise missing ticks
plt.xticks([1e-8, 1e-7, 1e-6, 1e-5, 1e-4, 1e-3, 1e-2, 1e-1, 1])

# Title : different multipoles
string_intel = '(CAMB-0.1.7) - '+type_GG_LL_GL+' - $C_{\ell}^{\'}$ relative of '+paramLatexArray[idParam]+'('+str(der)+' pts) at $z$ = '+str(zrange[idRedshift])+' - '+str(numel)+' pts'
plt.title(string_intel, fontsize = 20, pad = 25)

colorSimplePlot = ['b', 'r', 'g', 'k', 'y', 'm', 'c']

# Plot command 
for idMultipole in range(len(multipole)):
  plt.plot(stepNewArray[:], eval('matrixCl_der_'+str(der)+'[:, idMultipole, idParam, lx, ly]'), colorSimplePlot[idMultipole])

# Chose if negative or positive derivatives
# Plot with symlog or log along y-axis
# 1) For example : GG at z = 2.038 and l = 366
#    needs symlog with lintreshy = 1e-9
# 2) For example : LL at z = 2.038 and l = 366
#    needs nothing (even no log)
if (type_GG_LL_GL == 'GG'):
  plt.yscale('symlog', linthreshy = 1e-9)
elif (type_GG_LL_GL == 'LL'):
  plt.yscale('linear')

# Legend
plt.legend(['$l = 366.42$', '$l = 1079.28$', '$l = 1792.14$', '$l = 2505$',\
        '$l = 3217.85$', '$l = 3930.71$', '$l = 4643.57$'], fontsize=15, loc='best')

# Save plot
plt.savefig('Cl_derivative_Omega_m.pdf')

Anyone could see what I have got to do to display the minor xticks for each interval of the x axis logscale ?

I tried also by adding :

from matplotlib import ticker
from matplotlib.ticker import LogLocator

ax.tick_params(axis = 'x', which = 'major', pad = 15)
ax.xaxis.set_major_locator(LogLocator(base=10))
ax.xaxis.set_major_locator(LogLocator(base=10, subs=[1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0]))

But this doesn't work ...

In a second time, I would like also to have the control on the size of these minor ticks.

Thanks to @Quand Huang, I managed to do the following figure :

minor displayed

You can notice that Major ticks have disappeared and also the grid command, i.e by doing in my code snippet :

  minors = (0.1**np.arange(9)[:,None] * np.arange(0.1,1,0.1)).ravel()
  plt.yticks(fontsize = 20)
  plt.xscale('log')
  # Important otherwise missing ticks
  plt.xticks([1e-8, 1e-7, 1e-6, 1e-5, 1e-4, 1e-3, 1e-2, 1e-1, 1], fontsize = 40)
  plt.xticks(minors, fontsize = 20)
  plt.grid()

I tried to set a large font for manual major ticks (fontsize = 40) but it doesn't appear. By the way, why did grid mode disappear ?


Solution

  • You could generate the minor ticks like this:

    minors = (0.1**np.arange(9)[:,None] * np.arange(0.1,1,0.1)).ravel()
    
    plt.xscale('log')
    plt.xticks(minors);
    

    Output:

    enter image description here