A (proper) way to put minor ticks on duplicate y-axis?

Question:

The problem:

I try to create a simple plot with two identical y-axes (same numbers, same scale). However, I want one y-axis to have only major ticks, and another — to have both major and minor ticks.

The Minimal Working Example:

I created a twin y-axis, re-plotted the chart using this twin and set the locator for minor ticks.

import numpy as np
from datetime import date
from matplotlib import pyplot as plt
from matplotlib.ticker import AutoMinorLocator, AutoLocator


# matplotlib.__version__ = 3.3.3

dates = [date(2023, 3, 1),
date(2023, 3, 2),
date(2023, 3, 3),
date(2023, 3, 4),
date(2023, 3, 5)]

sample = np.arange(5)

fig, ax = plt.subplots(figsize=(4, 6), constrained_layout=True)
twin_y_ax = ax.twinx()

ax.yaxis.set_major_locator(AutoLocator())

ax.plot(dates, sample**2, linestyle = "dotted")

twin_y_ax.plot(dates, sample**2, linestyle = "dotted")
twin_y_ax.yaxis.set_major_locator(AutoLocator())
twin_y_ax.yaxis.set_minor_locator(AutoMinorLocator())

for label in ax.get_xticklabels(which="major"):
    label.set(rotation=30, horizontalalignment="right")

plt.show()

This solution got me what I wanted, but what if I am plotting 10 lines. Do I need to re-plot all of them using a twin axis?

Suggestions for improvement are appreciated.

Asked By: user136555

||

Answers:

I’m not sure I understand why you would replot your data on twin_y_ax. IIUC you could simply copy ax limits and ticks and add the minor ticks:

import numpy as np
from datetime import date
from matplotlib import pyplot as plt
from matplotlib.ticker import AutoMinorLocator, AutoLocator

dates = [date(2023, 3, 1),
date(2023, 3, 2),
date(2023, 3, 3),
date(2023, 3, 4),
date(2023, 3, 5)]

sample = np.arange(5)

fig, ax = plt.subplots(figsize=(4, 6), constrained_layout=True)

# plot everything you need on ax
ax.plot(dates, sample**2, linestyle = "dotted")

# create a twin with same limits and labels
twin_y_ax = ax.twinx()
twin_y_ax.yaxis.set_ticks(ax.get_yticks())
twin_y_ax.set_ylim(ax.get_ylim())
# add minor ticks
twin_y_ax.yaxis.set_minor_locator(AutoMinorLocator())

# also you can replace your loop with the following:
plt.setp(ax.xaxis.get_majorticklabels(), rotation=30, horizontalalignment="right")

plt.show()

Output:

enter image description here

Answered By: Tranbi
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.