3

I want to create a special plot with two x axis and one y axis. The bottom X axis increases in value, and the top X axis decreases in value. I have an x-y pair, for which I want to plot y over one x-axes and on the top x' axes with different scale: (x' = f(x)).

In my case, the conversion between x and x' is x' = c/x, where c is a constant. I found an example here, which deals with transformations of this kind. Unfortunately this example doesn't work for me (no error message, the output is just not transformed).

I am using python 3.3 and matplotlib 1.3.0rc4 (numpy 1.7.1)

Does anybody know a convenient way to do this with matplotlib?

EDIT: I found an answer on stackoverflow (https://stackoverflow.com/a/10517481/2586950) which helped me to get to the desired plot. As soon as I can post Images (due to Reputation-Limit), I will post the answer here, if anyone is interested.

Community
  • 1
  • 1
JHK
  • 639
  • 1
  • 7
  • 14

2 Answers2

2

I am not sure if this is what you're looking for but here it is anyway:

import pylab as py
x = py.linspace(0,10)
y = py.sin(x)
c = 2.0

# First plot
ax1 = py.subplot(111)
ax1.plot(x,y , "k")
ax1.set_xlabel("x")

# Second plot
ax2 = ax1.twiny()
ax2.plot(x / c, y, "--r")
ax2.set_xlabel("x'", color='r')
for tl in ax2.get_xticklabels():
    tl.set_color('r')

example

I was guessing this is what you meant by

I have an x-y pair, for which i want to plot y over one x-axes and under one x'-axes with different scalings.

But I apologise if I am wrong.

Greg
  • 11,654
  • 3
  • 44
  • 50
  • Hey, wow, fast answer. In principle the final graph should look like this, the only problem is: x' = c/x, its an inverse relationship - if i modify your example by switching c and x in the line ax2.plot(x / c, y, "--r") the two functions are not congruent anymore. – JHK Jul 16 '13 at 11:52
  • Of course they aren't you are still plotting the same y data but against a completely different scale. So it will still be a sin function but stretched as x->inf. You will also have problems at x=0. Try to draw with pencil and paper what you are looking for. – Greg Jul 16 '13 at 12:16
  • 1
    I think its safe to say that most of the people who post here know how function behave in dependence on its paramters and axis its plotted over. I just have trouble to make myself clear, im sorry. As noted in the edit up in question, I found an answer. I will post it as soon as possible, with a clarification what was asked. – JHK Jul 16 '13 at 15:22
1

the output of the following code is satisfactory for me - unless there is some more convenient way, I stick with that.

import matplotlib.pyplot as plt
import numpy as np

plt.plot([1,2,5,4])
ax1 = plt.gca()
ax2 = ax1.twiny()

new_tick_locations = np.array([.1, .3, .5, .7,.9]) # Choosing the new tick locations
inv = ax1.transData.inverted()
x = []

for each in new_tick_locations:
    print(each)
    a = inv.transform(ax1.transAxes.transform([each,1])) # Convert axes-x-coordinates to data-x-coordinates
    x.append(a[0])

c = 2
x = np.array(x)
def tick_function(X):
    V =  c/X
    return ["%.1f" % z for z in V]
ax2.set_xticks(new_tick_locations) # Set tick-positions on the second x-axes
ax2.set_xticklabels(tick_function(x)) # Convert the Data-x-coordinates of the first x-axes to the Desired x', with the tick_function(X)

A possible way to get to the desired plot.

JHK
  • 639
  • 1
  • 7
  • 14