Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

trouble aligning ticks for matplotlib twinx axes

I created a matplotlib plot that has 2 y-axes. The y-axes have different scales, but I want the ticks and grid to be aligned. I am pulling the data from excel files, so there is no way to know the max limits beforehand. I have tried the following code.

# creates double-y axis
ax2 = ax1.twinx()

locs = ax1.yaxis.get_ticklocs()
ax2.set_yticks(locs) 

The problem now is that the ticks on ax2 do not have labels anymore. Can anyone give me a good way to align ticks with different scales?

like image 815
amanda_mays Avatar asked Jul 11 '17 14:07

amanda_mays


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 align labels in MatPlotLib?

Since the writing of this question matplotlib has added an easy to use function that aligns labels. The correct way to force alignment of the labels is to use the function fig. align_labels() before showing the figure. If you need more fine grained control, you may also use the functions Figure.

How do I turn on minor ticks in MatPlotLib?

Minor tick labels can be turned on by setting the minor formatter. MultipleLocator places ticks on multiples of some base. StrMethodFormatter uses a format string (e.g., '{x:d}' or '{x:1.2f}' or '{x:1.1f} cm' ) to format the tick labels (the variable in the format string must be 'x' ).


1 Answers

Aligning the tick locations of two different scales would mean to give up on the nice automatic tick locator and set the ticks to the same positions on the secondary axes as on the original one.

The idea is to establish a relation between the two axes scales using a function and set the ticks of the second axes at the positions of those of the first.

enter image description here

import matplotlib.pyplot as plt
import matplotlib.ticker

fig, ax = plt.subplots()
# creates double-y axis
ax2 = ax.twinx()

ax.plot(range(5), [1,2,3,4,5])
ax2.plot(range(6), [13,17,14,13,16,12])
ax.grid()

l = ax.get_ylim()
l2 = ax2.get_ylim()
f = lambda x : l2[0]+(x-l[0])/(l[1]-l[0])*(l2[1]-l2[0])
ticks = f(ax.get_yticks())
ax2.yaxis.set_major_locator(matplotlib.ticker.FixedLocator(ticks))

plt.show()

Note that this is a solution for the general case and it might result in totally unreadable labels depeding on the use case. If you happen to have more a priori information on the axes range, better solutions may be possible.

Also see this question for a case where automatic tick locations of the first axes is sacrificed for an easier setting of the secondary axes tick locations.

like image 190
ImportanceOfBeingErnest Avatar answered Sep 22 '22 16:09

ImportanceOfBeingErnest