twinx non-linear mapping between shared y axes on a plot in matplotlib

Viewed 232

I have some 3d data that I am plotting with pcolormesh.

On the x-axis is time, on the y-axis is height.

The height has a potential (E) associated with it, but the mapping from height (y) to potential (E) is non-linear.

I want to add an axis on the right hand side of my figure showing the potential that is correct based on the values on the left hand side. I do not particularly care about the left and right ticks lining up (as is the case in this solution). If anything 'nice number' ticks on the right axis would be useful.

I have tried setting the ylim of the top and bottom points as per the celsius-farenheit example in the matplotlib docs, but this assumes a linear scale between the start and end point which is not the case here.

Finally I tried using a funcformatter, but the scaling for the potential requires two external constants to be given, and I can't find a way that constants can be passed to a funcformatter.

So far my code looks like:

import numpy as np
import matplotlib.pyplot as plt


time = np.arange(0.0, 11.0, 1.0)
y = np.arange(0.0, 11.0, 1.0)
data = np.random.randint(1,100, size=(11,11))

fig,ax=plt.subplots(1,1)

im=ax.pcolormesh(time,y,data,shading='nearest')
ax.set_xlabel('time')
ax.set_ylabel('height')
ax.set_ylim(y.min(),y.max())

ax_E = ax.twinx()
ax_E.set_ylabel('Potential E')

plt.savefig('test.png')

Currently the right hand y axis has a linear scale from 0 to 1.0. I would like this replacing with a scale showing the potential correct according to the values of y on the left hand y-axis.

The function I want to use for the potential is something like:

def get_E(mu, ymax, y):
    p2 = 2.0*mu/ymax**3
    Jmin = 2.0*np.sqrt(p2)*ymax
    pmin = Jmin/(2.0*y)
    E = np.sqrt(mu**2*pmin**2 + mu**2) - mu
    return E

i.e. highly nonlinear, with 2 constants (mu and ymax) passed to it.

Any help you can give would be greatly appreciated. I have done my best to search for a solution to this specific problem already, but my apologies if I have missed anything. Please do ask any questions to clarify.

0 Answers
Related