1

I'm trying to display two different functions in a common plot with two differently scaled y-axes. Still, the grid lines should be aligned. And I'd like to use the nice autolocator algorithm for the tick positions of the first y-axis. I've tried and tried but I can't get the scaling right for the second y-axis.

# -*- coding: utf-8 -*-
"""
MWE for copying tick positions between y-axes
"""
from __future__ import print_function
import matplotlib.pyplot as plt
import numpy as np

def tick_function(x1):
    """ transform tick positions """
    x2 = x1 / 78.3
    return ["{0:.1f}".format(x) for x in x2]

x = np.arange(100)

plt.close('all')
fig1 = plt.figure(1)
ax1 = fig1.add_subplot(111)
ax1.plot(x, x*x)
ax1.set_xlabel(r"$x \rightarrow$")
ax1.set_ylabel(r"$x^2 \rightarrow$")
ax1_yticks = ax1.get_yticks() # get positions of the ax1 y-ticks in data coordinates
ax1_y_bounds = ax1.get_ybound() # get lower and upper limit of ax1 y-ticks

ax2 = ax1.twinx() # create 2nd y-axis
ax2.set_yticks(ax1_yticks) 
ax2.set_ybound(ax1.get_ybound())
ax2.set_yticklabels(tick_function(ax1_yticks))
ax2.autoscale(False)
ax2.plot(x,x)
ax2.set_ylabel(r'$x \rightarrow$')
ax1.grid(True)

fig1.set_tight_layout(True)
plt.show()

Twin y-axes, wrong scaling

Moving the second plot command before the ax2.set_yticklabel ... command obtains a different scaling but now the labels are missing (or maybe shifted outside the plot):

enter image description here

@importanceofbeingernest: Thanks, I missed that post - I've updated and attached the code that solves my problem. The "unperfect" scaling is not a problem for my real-world problem. But do you have any idea, whether it is possible to automatically update the second axes when zooming in?

# -*- coding: utf-8 -*-
"""
MWE for copying tick positions between y-axes
"""
from __future__ import print_function
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
import numpy as np

x = np.arange(100)

plt.close('all')
fig1 = plt.figure(1)
ax1 = fig1.add_subplot(111)
ax1.plot(x, x*x)
ax1.set_xlabel(r"$x \rightarrow$")
ax1.set_ylabel(r"$x^2 \rightarrow$")
ax1.grid(True)
ax1_yticks = ax1.get_yticks() # get positions of the ax1 y-ticks in data coordinates

ax2 = ax1.twinx() # create 2nd y-axis
ax2.plot(x,x)
ax2.set_ylabel(r'$x \rightarrow$')

l1 = ax1.get_ylim() # get y-limits for ax1 
l2 = ax2.get_ylim() # and ax2
# map yticks(ax1) ->  yticks(ax2) to cover the same range on both axes
f = lambda x : l2[0]+(x-l1[0])/(l1[1]-l1[0])*(l2[1]-l2[0])
ax2_yticks = f(ax1_yticks)
 # fix tick locations for ax2:
ax2.yaxis.set_major_locator(ticker.FixedLocator(ax2_yticks))

fig1.set_tight_layout(True)
plt.show()

enter image description here

Chipmuenk
  • 607
  • 1
  • 7
  • 22
  • 1
    I do have problems understanding the issue you have. But it seems that this is the same question as this one: https://stackoverflow.com/questions/45037386/trouble-aligning-ticks-for-matplotlib-twinx-axes – ImportanceOfBeingErnest Jul 14 '17 at 10:22

0 Answers0