3

This is based on generating a second x-axis, as described in this previous post:

matplotlib: adding second axes() with transparent background?

Included below is code to generate a plot with two x-axis that represent two different time units for the same data: relative time (rel_time) and an absolute time (abs_time). While the method described above nicely generates the two axes, the data is scaled differently between them.

How can I generate a plot with two x-axes that are linked? That is, the data plotted on both each axis should be aligned with the other.

Furthermore, is there a way to do this without plotting the data (y) twice? In the end the data should be aligned, so the second plot is just there to generate a new axis.

The code below:

# Based on question:
# https://stackoverflow.com/questions/7761778/matplotlib-adding-second-axes-with-transparent-background
import time
import numpy as np
import matplotlib.pyplot as plt

# Plot Data
rel_time = np.arange(-10.0, 40)  # seconds
abs_time = rel_time + time.time()  # epoch time
y = np.array([1.1, 1.2, 1.2, 1.1, 1.2, 1.1, 1.3, 1.3, 1.2, 1.1, 1.4, 1.7, 
              2.5, 2.6, 3.5, 4, 4.3, 4.8, 5, 4.9, 5.3, 5.2, 5.5, 5.1, 
              5.4, 5.6, 5.1, 6, 6.2, 6.2, 5.5, 6.1, 5.4, 6.3, 6.2, 6.5,
              6.3, 6.1, 6.5, 6.6, 6.1, 6.6, 6.5, 6.4, 6.6, 6.5, 6.2, 6.6,
              6.4, 6.8])  # Arbitrary data

fig = plt.figure()
fig.subplots_adjust(bottom=0.25)  # space on the bottom for second time axis

host = fig.add_subplot(111)  # setup plot

p1 = host.plot(rel_time, y, 'b-')  # plot data vs relative time
host.set_xlabel("Relative Time [sec]")
host.set_ylabel("DATA")

newax = host.twiny()  # create new axis
newax.set_frame_on(True)
newax.patch.set_visible(False)
newax.xaxis.set_ticks_position('bottom')
newax.xaxis.set_label_position('bottom')
newax.spines['bottom'].set_position(('outward', 50))
newax.plot(abs_time, y, 'k-')  # plot data vs relative time
newax.set_xlabel("Absolute Time [Epoch sec]")

plt.show()

generates a timeseries plot with mismatched x-axes: Timeseries Plot with mismatched x-axes that display different time units

Community
  • 1
  • 1
BFTM
  • 3,225
  • 6
  • 23
  • 22
  • So you want exactly the same figure but without the blue curve? – fraxel May 09 '12 at 16:39
  • I want the second axis (Absolute Time) to line up exactly with the first (Relative Time). If that were the case, the blue curve would be hidden under the black. When curves overlap, I don't see the point in explicitly drawing one of them (say the blue curve). I have other datasets where the mismatch between axis is much more profound. – BFTM May 09 '12 at 16:56

1 Answers1

5

You need to specify limits for your x-axes. If you add these lines it will do it:

host.set_xlim(rel_time[0],rel_time[-1])
newax.set_xlim(abs_time[0],abs_time[-1])

both curves plotted:

enter image description here

If you don't want to draw the data twice, just delete the newax.plot()line.

fraxel
  • 34,470
  • 11
  • 98
  • 102
  • That's exactly what I was looking for. If I want to plot outside the range of the timeseries data (e.g., to leave whitespace on either side of the time data), I guess I'd have to explicitly state the in one time axis and then convert the time endpoints into the other timebase. Unless there is a better way? – BFTM May 09 '12 at 17:51
  • @BFTM - Great :) , and yes you're right, just change `(rel_time[0],rel_time[-1])` to `(rel_time[0] - 1 ,rel_time[-1] + 1)` for example.. – fraxel May 09 '12 at 18:51