Is this what you want? I think the n_skip keyword does what you want. I
can't remember where the file came from, so I've posted the code
instead of a link:
-------
;+
; NAME:
; non_linear_axis
;
; PURPOSE:
; Draw an axis for a quantity that varies non-linearly
;
; CATEGORY:
; Plotting
;
; CALLING SEQUENCE:
; non_linear_axis,
;
; INPUTS:
; v = fltarr(n_v): array of values corresponding to existing
axis
; u = fltarr(n_v): array of values u corresponding to v: u =
f(v)
;
; KEYWORD PARAMETERS:
; pos = ??? something to do with positioning the labels but I can't
remember
; just what
; format= format for axis labels. Default = '(I)'
; title = title for axis. Default is no title
; yaxis = 1: indicates an y axis (vertical) is to be drawn.
Default: x axis
; charsize = size of characters. Default = 1
; flip = not set: characters printed for top x axis or right y axis,
; set: characters printed for bottom x axis or left y axis
; tic_fac = length of tick marks relative to default of 1
; n_skip = preserve only every n_skip'th label
;
; EXAMPLE:
; Let f be an array of frequency values in wavenumbers and s be the
; corresponding spectrum. To plot the spectrum versus wavenumber
and then
; draw a wavelength scale on the top axis:
; (Assume f goes from 2200 to 2500 cm-1. wavelength =
1e4/wavenumber)
;
plot,f,s,xstyle=8,ymargin=[5,5],xtitle='Wavenumber',ytitle=' Spectrum'
; u=[4.1, 4.2, 4.3, 4.4, 4.5] ;lable the new axis with
these values
; non_linear_axis, 1e4/u, u, format = '(f5.1)', title =
'Wavelength'
;
; MODIFICATION HISTORY:
; William Gallery, AER, Inc., May, 1997
; Dec., 1998: added n_skip parameter
; limited ticks and labels to range of existing axis
;-
PRO Non_linear_axis, v, u, du, pos=pos, format=format, title=title,
yaxis=yaxis, $
charsize=charsize, flip=flip, tick_fac=tick_fac, $
n_skip=n_skip ,minors=minors
IF n_elements(charsize) LE 0 THEN charsize = 1.
IF n_elements(yaxis) GT 0 THEN axis = 'y' ELSE axis = 'x'
IF n_elements(flip) LE 0 THEN BEGIN
sign = 1 ;characters above or to right of axis
orig = 1 ;top or right axis
ofset = 0 ;offset characters above or to right
of axis
ENDIF ELSE BEGIN
sign = -1 ;characters below or to left of axis
orig = 0 ;bottom or left axis
ofset = 1 ;offset characters below or to left of
axis
ENDELSE
if n_elements(tick_fac) le 0 then tick_fac = 1. ;scale factor for
tickmarks
IF n_elements(pos) LE 0 THEN BEGIN
axis_coord = convert_coord(!X.crange, !Y.crange, /data, /to_data)
CASE axis OF
'x': pos = !Y.crange(orig) ;y position of x axis, bottom or
top
'y': pos = !X.crange(orig) ;x position of y axis, right or
left
ENDCASE
ENDIF
IF n_elements(title) LE 0 THEN title = ''
IF n_elements(format) LE 0 THEN fmt = '(I)' ELSE fmt = format
IF n_elements(n_skip) LE 0 THEN n_skip = 1
;;Limit ticks and labels to within the range of the existing axis
;CASE axis OF
; 'x': w = where(u GE !x.crange(0) AND u LE !x.crange(1))
; 'y': w = where(u GE !y.crange(0) AND u LE !y.crange(1))
;ENDCASE
;uu = u(w)
;vv = v(w)
uu=u
vv=v
n_vv = n_elements(vv)
;;Need the height of a character in data coordinates
ch_size = [!D.x_ch_size/(!D.x_size*!X.s(1)), $
!D.y_ch_size/(!D.y_size*!Y.s(1))]*charsize
;;Convert uu to a string array
s_u = strtrim(string(uu, format=fmt), 2)
;;Find length of longest element of s_u
s_len_max = max(strlen(s_u))
;;Draw axis line
CASE axis OF
'x': BEGIN
;;Draw the axis line
plots, !X.crange, [!Y.crange(orig), !Y.crange(orig)], /data
;;Plot tick marks for uu
FOR k=0, n_vv-1 DO BEGIN
plots, [vv(k), vv(k)], [ pos,
pos-sign*ch_size(1)*tick_fac], /data
ENDFOR
;;Print the values of uu centered above the tick mark
FOR k=0, n_vv-1, n_skip DO $
xyouts, vv(k), pos+sign*(ch_size(1)+ofset)*0.4, $
/data, align=.5, charsize=charsize, s_u(k)
IF n_elements(minors) gt 0 THEN BEGIN
FOR k=0, n_elements(minors)-1 DO BEGIN
plots, [minors[k], minors[k]], [ pos,
pos-sign*ch_size(1)*tick_fac/2], /data
ENDFOR
endif
;;Print the title above the top axis
xyouts, total(!X.crange)/2., pos+sign*(ch_size(1)+ofset)*2,
/data, $
align=.5, charsize=charsize*1.0, title
END
'y': BEGIN
;;Draw axis line
plots, [!X.crange(1), !X.crange(1)], !Y.crange, /data
;;Plot tick marks for u
FOR k=0, n_vv-1 DO BEGIN
plots, [pos, pos+sign*ch_size(0)*.6*tick_fac], [vv(k),
vv(k)], /data
ENDFOR
;;Print the values of u to the right of the tick mark
FOR k=0, n_vv-1, n_skip DO $
xyouts, pos+sign*ch_size(0)*(s_len_max*orig+1), $
vv(k)-ch_size(1)*.4, /data, align=1, charsize=charsize,
s_u(k)
IF n_elements(minors) gt 0 THEN BEGIN
FOR k=0, n_elements(minors)-1 DO BEGIN
plots, [pos, pos+sign*ch_size(0)*.6*tick_fac/2],
[minors(k), minors(k)], /data
ENDFOR
endif
;;Print the title outside the axis
xyouts, pos+sign*ch_size(0)*(s_len_max+3), total(!Y.crange)/2,
$
/data, align=.5, charsize=charsize*1.0, orien=180+sign*90.,
title
END
ENDCASE
return
END
pro example
; Let f be an array of frequency values in wavenumbers and s be the
; corresponding spectrum.
f=findgen(300)+2200 ;f goes from 2200 to 2500 cm-1. wavelength =
1e4/wavenumber)
s=sin(f/10)
; To plot the spectrum versus wavenumber and then draw a wavelength
scale on the top axis:
plot,f,s,xstyle=8,ymargin=[5,5],xtitle='Wavenumber',ytitle=' Spectrum'
u=[4.1, 4.2, 4.3, 4.4, 4.5] ;lable the new axis with
these values
non_linear_axis, 1e4/u, u, format = '(f5.1)', title = 'Wavelength'
end
-------
burkina wrote:
> Thanks Benjamin,
>
> but this is not what I'm looking for, because the two axes have
> different spacings, since they're not linear to each other.
> If I try that code on my plot, I get right major ticks at exactly the
> same places of the major ticks of the other axis, that is at values
> like 1.03, 0.89, 0,77, 0.69..., i.e. with spacing of 14, 12, 8...
> which is not what I want! In this case, also, the minor ticks are
> meaningless, they are only equally spaced.
> I want, as in the code I posted before, major ticks at values of 1,
> 0.9, 0.8, at the right places, corresponding to the right wavelenghts
> (and not to the major ticks of the other axis) and minor ticks at 0.99,
> 0.98, 0.97 a the right places, without the labels.
>
> There must be a way to do that!
>
> Thanks,
>
> Stefano
|