0

I am trying to plot some data from a .fits file that contains count rate vs time. My goal is to over plot the count rates of different events in the same plot, with different times on three different x-axis. As the events I want to plot are periodic, I imposed a condition on the identification of the right times, so I can extract count rates only from the time ranges I need. This is my effort:

#!/usr/bin/env python

from scipy import *
from numpy import *
from pylab import *
from scipy import optimize
import pyfits, os, re, glob
import matplotlib.pyplot as plt
import matplotlib as mpl
from matplotlib.ticker import FuncFormatter

rc('font',**{'family':'serif','serif':['Helvetica']})
rc('ps',usedistiller='xpdf')
rc('text', usetex=True)

#------------------------------------------------------

tmin=56200
tmax=56249

data=pyfits.open('http://heasarc.gsfc.nasa.gov/docs/swift/results/transients/weak/GX304-1.orbit.lc.fits')

time  = data[1].data.field(0)/86400. + data[1].header['MJDREFF'] + data[1].header['MJDREFI']
rate  = data[1].data.field(1)
error = data[1].data.field(2)
data.close()

cond= ((time > tmin-5) & (time < tmax)) | ((time + 132.5 > tmin) & (time + 132.5 < tmax-10)) | ((time + 265 > tmin) & (time + 265 < tmax-12))
time=time[cond]
rate=rate[cond]
error=error[cond]

fig, ax1 = plt.subplots()
newax2 = ax1.twiny()
newax3 = ax1.twiny()

# Make some room at the bottom
fig.subplots_adjust(bottom=0.30)

newax2.set_frame_on(True)
newax2.patch.set_visible(False)
newax2.xaxis.set_ticks_position('bottom')
newax2.xaxis.set_label_position('bottom')
newax2.spines['bottom'].set_position(('outward', 20))

newax3.set_frame_on(True)
newax3.patch.set_visible(False)
newax3.xaxis.set_ticks_position('bottom')
newax3.xaxis.set_label_position('bottom')
newax3.spines['bottom'].set_position(('outward', 40))

#..plot the current light curve
errorbar(time, rate, error, fmt='r.', capsize=0)
gca().xaxis.set_major_formatter(FormatStrFormatter('%5.1f'))

#..overplot a previous outburst
errorbar(time + 122.5, rate, error, fmt='g.', capsize=0)
errorbar(time + 255, rate, error, fmt='k.', capsize=0)

axis([tmin-10,tmax,-0.00,0.45])
xlabel('Time, MJD')
ylabel("BAT cts/s/cm$^2$")
savefig("sync.eps",orientation='portrait',papertype='a4',format='eps')
os.system('gv sync.eps')

I am plotting three events, so I need three x-axis; however, I would like to write the correspective times on the x-axis with the correspective color too, if possible. The time reported on the bottom line is the correct one for the red curve, that is the most recent event. Any suggestions, please? Many thanks in advance.

4

1 に答える 1

0

If I understand your question correctly, the problem are the incorrect ticks on the first and second x axes. You should simply tie the errorbar functions to the correct axis, and then matplotlib will do the scaling for you. Like this:

...
#..plot the current light curve
ax1.errorbar(time, rate, error, fmt='r.', capsize=0)
gca().xaxis.set_major_formatter(FormatStrFormatter('%5.1f'))

#..overplot a previous outburst
newax2.errorbar(time + 122.5, rate, error, fmt='g.', capsize=0)
newax3.errorbar(time + 255, rate, error, fmt='k.', capsize=0)
...

I generally prefer the more object-oriented approach in matplotlib anyway, so then this is the only way to do it.

I'll leave the colouring part to the reference in my comment, if you don't mind.

Update

Below is some updated code; perhaps this is what you're looking for. The trick is to not move the x data (time), but simply shift the x limits (the "window" you're looking at) to what you want. So I applied the 122.5 and 255 offsets (reversed) to the x limits of each axes separately.

I also had to set the formatter for each axes separately; if I don't set the formatter, you end up with, for example, an offset notation (0 .. 10 .. 20 .. 30 + 56190). Using the global formatter like you had, works (I think) only on ax1. Note that I only set the y limits globally, commenting out the axis command.

...
##..plot the current light curve
ax1.errorbar(time, rate, error, fmt='r.', capsize=0)
ax1.set_xlim(tmin-10,tmax)
ax1.xaxis.set_major_formatter(FormatStrFormatter('%5.1f'))
##..overplot a previous outburst
newax2.errorbar(time, rate, error, fmt='g.', capsize=0)
newax3.errorbar(time, rate, error, fmt='k.', capsize=0)
newax2.set_xlim(tmin-10-122.5,tmax-122.5)
newax2.xaxis.set_major_formatter(FormatStrFormatter('%5.1f'))
newax3.set_xlim(tmin-10-255,tmax-255)
newax3.xaxis.set_major_formatter(FormatStrFormatter('%5.1f'))
ylim(0,0.45)
#axis([tmin-10,tmax,-0.00,0.45])
...

This results in enter image description here which is what your original script produces, but with a hopefully correct set of x-axes (apart from the colouring).

于 2013-03-14T15:12:26.743 に答える