matplotlib force denser major ticks on logaritmic axis of a small plot

118 views Asked by At

I have a matplotlib plot with logartihmic X axis, that I want to save as pgf and include it into my latex document. At the desired size matplotlib does not label every round power of the base=10 in the X axis. On the other hand, if I increase the size of the plot, they are shown together with the minor axes. I've found LogLocator, but I was not able to convince it to produce an output I would like to achieve.

The difference between matplotlib output and the desired output: enter image description here

The code I was using:

import numpy as np
import matplotlib
import matplotlib.pyplot as plt

matplotlib.use('pgf')
pgf_with_custom_preamble = {
    "pgf.texsystem": "pdflatex",
    "font.family": "serif", # use serif/main font for text elements
    "text.usetex": True,    # use inline math for ticks
    "pgf.rcfonts": False,   # don't setup fonts from rc parameters
    "figure.figsize": (3.3914487339144874*0.5, 2.0960305886619515*0.8),
    "axes.labelsize": 8,
    "axes.grid": True,
    "font.size": 7,
    "legend.fontsize": 8,
    "legend.handlelength": 2,
    "legend.handletextpad": 0.4,
    "legend.columnspacing": 1,
    "xtick.labelsize": 8,
    "ytick.labelsize": 8,
    "xtick.direction":"in",
    "ytick.direction":"in",
    "xtick.major.size":1.5,
    "ytick.major.size":1.5,
    "grid.alpha": 0.6,
    "lines.markersize": 4,
    "savefig.pad_inches":0,
    "savefig.bbox":"tight",
    "savefig.dpi":300,
    "pgf.preamble": r"\usepackage[detect-all,locale=US]{siunitx}\usepackage{amsmath}\usepackage[utf8x]{inputenc}\usepackage[T1]{fontenc}"
}
matplotlib.rcParams.update(pgf_with_custom_preamble)

freq = np.logspace(3,8,100)
gain = 50*np.random.random_sample(100)-20

fig, ax = plt.subplots()
ax.grid(True,which='minor', alpha=0.3, axis='both')
ax.grid(True,which='major', alpha=0.7, axis='both')
ax.set_xscale('log')
ax.tick_params(axis='both', which='major', pad=2)
ax.set_ylim(-20,30)
ax.set_xlim(1e3,3e7)
ax.yaxis.set_minor_locator(matplotlib.ticker.MultipleLocator(2.5))
ax.scatter(freq, gain)
plt.tight_layout()
fig.savefig("mwe.pgf")    

fig, ax = plt.subplots(figsize=(3.3914487339144874*0.5*1.5, 2.0960305886619515*0.8*1.5))
ax.grid(True,which='minor', alpha=0.3, axis='both')
ax.grid(True,which='major', alpha=0.7, axis='both')
ax.set_xscale('log')
ax.tick_params(axis='both', which='major', pad=2)
ax.set_ylim(-20,30)
ax.set_xlim(1e3,3e7)
ax.yaxis.set_minor_locator(matplotlib.ticker.MultipleLocator(2.5))
ax.scatter(freq, gain)
plt.tight_layout()
fig.savefig("mwe2.pgf")

An MWE latex document:

\documentclass{article}
\usepackage{siunitx}
\usepackage{amsmath}
\usepackage{pgf}
\usepackage{graphicx}

\begin{document}
\begin{figure}
  \centering
  \input{../mwe.pgf}
  \qquad
  \input{../mwe2.pgf}
  \caption{How to force the same X axis ticklabels from the right hand plot to the left hand plot}
  \label{fig:label}
\end{figure}
\end{document}
1

There are 1 answers

0
Horror Vacui On

I was just one try from the solution. The following line will do the trick:

ax.xaxis.set_major_locator(matplotlib.ticker.LogLocator(base=10, subs=[1], numticks=6))
ax.xaxis.set_minor_locator(matplotlib.ticker.LogLocator(base=10, subs=[1,2,3,4,5,6,7,8,9],numticks=9))