I'm plotting two datasets with different units on the y-axis. Is there a way to make the ticks and gridlines aligned on both y-axes?
The first image shows what I get, and the second image shows what I would like to get.
This is the code I'm using to plot:
import seaborn as sns
import numpy as np
import pandas as pd
np.random.seed(0)
fig = plt.figure()
ax1 = fig.add_subplot(111)
ax1.plot(pd.Series(np.random.uniform(0, 1, size=10)))
ax2 = ax1.twinx()
ax2.plot(pd.Series(np.random.uniform(10, 20, size=10)), color='r')
I wrote this function that takes Matplotlib axes objects ax1, ax2, and floats minresax1 minresax2:
It calculates and sets the ticks such that there are seven ticks. The lowest tick corresponds to the current lowest tick and increases the highest tick such that the separation between each tick is integer multiples of minrexax1 or minrexax2.
To make it general, you can set the total number of ticks you want by changing ever
7
you see to the total number of ticks, and change6
to the total number of ticks minus 1.I put a pull request in to incorporate some this into matplotlib.ticker.LinearLocator:
https://github.com/matplotlib/matplotlib/issues/6142
In the future (Matplotlib 2.0 perhaps?), try:
That should just work and choose convenient ticks for both y-axes.
I had the same issue except this was for a secondary x axis. I solved by setting my secondary x axis equal to the limit of my primary axis.The example below is without setting the limit of the second axis equal to the first:
ax2 = ax.twiny()
Once I set the limit of the second axis equal to the first
ax2.set_xlim(ax.get_xlim())
here is my result:This code will ensure that grids from both axes align to each other, without having to hide gridlines from either set. In this example, it allows you to match whichever has the finer grid lines. This builds off of the idea from @Leo. Hope it helps!
this has already been properly answered a while ago: trouble aligning ticks for matplotlib twinx axes
(the answer given in here is not at all working for a general case)
I could solve it by deactivating
ax.grid(None)
in one of the grid`s axes:I am not sure if this is the prettiest way to do it, but it does fix it with one line: