pro specplot,x,y,z,limits=lim,data=data,overplot=overplot,overlay=overlay,$
ps_resolution=ps_res,x_no_interp=x_no_interp,y_no_interp=y_no_interp, $
no_interp=no_interp, ignore_nan=ignore_nan, $
dx_gap_size=dx_gap_size
compile_opt idl2
opt = {xrange:[0.,0.],yrange:[0.,0.],zrange:[1.,1.]}
if keyword_set(dx_gap_size) then dg=dx_gap_size else str_element,lim,'datagap',dg
if keyword_set(data) then begin
x = struct_value(data,'x')
y = struct_value(data,'v')
z = struct_value(data,'y')
if not keyword_set( y ) and size(/n_dimen,y) eq 0 then begin
y = struct_value(data,'v2')
z = total(z,2)
endif
extract_tags,opt,data,except=['x','y','v']
if keyword_set(dx_gap_size) then dg=dx_gap_size else str_element,lim,'datagap',dg
if size(/n_dimen,z) eq 1 then begin
dprint,dlevel=2,'Warning! One dimensional array provided. Kludging by increasing dimension.'
z = [[z],[z]]
y = [y-.5,y+.5]
endif
endif
if keyword_set(no_interp) then begin
x_no_interp=1
y_no_interp=1
endif
if keyword_set(dg) then begin
tdif = [x[1:*]-x[0:n_elements(x)-2]]
if dg lt 0 then begin
posindx = where(tdif gt 0,poscnt)
dg = 20d*min(tdif[posindx])
endif
dprint,dlevel=3,verbose=verbose,'No plot interpolation for data gaps longer than ', $
strcompress(dg,/remove_all),' seconds.'
gapindx = where(tdif gt dg, gapcnt)
if gapcnt gt 0 then begin
seg0 = lonarr(gapcnt+1)
seg1 = seg0
seg1[gapcnt] = n_elements(x)-1
for i=0L,gapcnt-1 do begin
seg0[i+1] = gapindx[i]+1
seg1[i] = gapindx[i]
endfor
endif else begin
seg0 = 0L
seg1 = n_elements(x)-1
endelse
endif else begin
gapcnt = 0
seg0 = 0L
seg1 = n_elements(x)-1
endelse
xtemp = x
ytemp = y
ztemp = z
extract_tags,opt,lim
str_element,opt,'xlog',value=xlog
str_element,opt,'ylog',value=ylog
str_element,opt,'zlog',value=zlog
str_element,opt,'gifplot',value=gifplot
if keyword_set(gifplot) then begin
x_no_interp = 1
y_no_interp = 1
no_color_scale = 1
endif
str_element,opt,'x_no_interp',value=x_no_interp
str_element,opt,'y_no_interp',value=y_no_interp
str_element,opt,'no_interp',value=no_interp
if keyword_set(no_interp) then begin
x_no_interp=1
y_no_interp=1
endif
str_element,opt,'max_value',value=mx
str_element,opt,'min_value',value=mn
str_element,opt,'bottom',value=bottom
str_element,opt,'top', value=top
if opt.zrange[0] eq opt.zrange[1] then begin
if keyword_set(zlog) then begin
good = where(finite(alog(z)),goodcnt)
if goodcnt gt 0 then begin
zrange = minmax(z[good],min_value=mn,max_value=mx)
endif else begin
zrange = [0,0]
endelse
endif else begin
zrange = minmax(z,/nan,min_value=mn,max_value=mx)
endelse
endif else begin
zrange = opt.zrange
endelse
ydim = size(y,/n_dim)
no_color_scale=1
for j=0L,gapcnt do begin
x = xtemp[seg0[j]:seg1[j]]
if ydim eq 1 then y=ytemp else y=ytemp[seg0[j]:seg1[j],*]
z = ztemp[seg0[j]:seg1[j],*]
if n_params() eq 1 then begin
dim = dimen(x)
specplot,findgen(dim[0]),findgen(dim[1]),x,limits=lim,overplot=overplot,$
overlay=overlay,ps_resolution=ps_res, $
x_no_interp=x_no_interp,y_no_interp=y_no_interp
return
endif
if opt.xrange[0] eq opt.xrange[1] then opt.xrange = minmax(x)
if opt.yrange[0] eq opt.yrange[1] then opt.yrange = minmax(y)
if not keyword_set(overplot) then box,opt
y1 = y
if keyword_set(ylog) then begin
bad = where( finite(y1) eq 0, c)
if c ne 0 then y1[bad] = 0.
bad = where(y1 le 0,c)
if c ne 0 then y1[bad] = !values.f_nan
y1 = alog10(y1)
endif
if keyword_set(xlog) then x1 = alog10(x) else x1 = x
str_element,opt,'minzlog',value=minzlog
z1 = z
if keyword_set(zlog) then begin
bad = where( finite(z1) eq 0, cbad)
if cbad ne 0 then z1[bad] = !values.f_nan
neg = where(z1 le 0,cneg)
if keyword_set(minzlog) then begin
posrange = minmax(z1,/pos)
negvals = posrange[0]/10.
endif else negvals = 0
if cneg ne 0 then z1[neg] = negvals
z1 = alog10(z1)
zrange_new = alog10(zrange)
endif else begin
zrange_new = zrange
endelse
str_element,lim,'extend_y_edges',value=extend_y_edges,success=success
if success && extend_y_edges then begin
extend_y_dim = dimen(y1)
if n_elements(extend_y_dim) eq 1 && extend_y_dim[0] gt 1 then begin
y_diff_low = (y1[1]-y1[0])/2.
y_diff_high = (y1[extend_y_dim-1] - y1[extend_y_dim-2])/2.
if y_diff_low gt 0 and y_diff_high gt 0 then begin
z1=[[z1[*,0]],[z1],[z1[*,extend_y_dim-1]]]
y1=[y1[0]-y_diff_low,y1,y1[extend_y_dim-1]+y_diff_high]
endif
endif else if n_elements(extend_y_dim) gt 1 && extend_y_dim[1] gt 1 then begin
y_diff_low = (y1[*,1]-y1[*,0])/2.
y_diff_high = (y1[*,extend_y_dim[1]-1] - y1[*,extend_y_dim[1]-2])/2.
idx = where(y_diff_low eq 0 or y_diff_high eq 0,c)
if c eq 0 then begin
z1=[[z1[*,0]],[z1],[z1[*,extend_y_dim[1]-1]]]
y1=[[y1[*,0]-y_diff_low],[y1],[y1[*,extend_y_dim[1]-1]+y_diff_high]]
endif
endif
endif
xwindow=!x.window
ywindow=!y.window
xcrange=!x.crange
ycrange=!y.crange
overlay = struct_value(opt,'overlay',default=1)
if gapcnt gt 0 then overlay=1
if keyword_set(overlay) then begin
x_minmax = keyword_set(xlog) ? 10.^minmax(x1) : minmax(x1)
y_minmax = keyword_set(ylog) ? 10.^minmax(y1) : minmax(y1)
winpos = convert_coord(x_minmax,y_minmax,/data,/to_norm)
xwr = minmax(winpos[0,*])
ywr = minmax(winpos[1,*])
xwindow = xwindow > xwr[0]
xwindow = xwindow < xwr[1]
ywindow[0] = ywindow[0] > ywr[0]
ywindow[1] = ywindow[1] < ywr[1]
datpos = convert_coord(xwindow,ywindow,/norm,/to_data)
xcrange = reform(datpos[0,*])
ycrange = reform(datpos[1,*])
if !x.type then xcrange = alog10(xcrange)
if !y.type then ycrange = alog10(ycrange)
endif
pixpos = round(convert_coord(xwindow,ywindow,/norm,/to_device))
npx = pixpos[0,1]-pixpos[0,0]+1
npy = pixpos[1,1]-pixpos[1,0]+1
xposition = pixpos[0,0]
yposition = pixpos[1,0]
if npx gt 0 and npy gt 0 then begin
str_element,opt,'ignore_nan',ignore_nan
if keyword_set(ignore_nan) then begin
wg = where(finite(total(z1,2)),c)
if c gt 0 then begin
z1 = z1[wg,*]
y1 = y1[wg,*]
x1 = x1[wg]
endif
endif
if !d.flags and 1 then begin
if keyword_set(ps_res) then ps_resolution=ps_res else ps_resolution = 150.
str_element,opt,'ps_resolution',value=ps_resolution
dprint,dlevel=4,ps_resolution
scale = ps_resolution/!d.x_px_cm/2.54
endif else scale = 1.
yd = ndimen(y1)
if yd eq 1 then begin
nypix = round(scale*npy)
ny = n_elements(y1)
yp = findgen(nypix)*(ycrange[1]-ycrange[0])/(nypix-1) + ycrange[0]
ys = interp(findgen(ny),y1,yp)
if keyword_set(y_no_interp) then ys = round(ys)
nxpix = round(scale*npx)
if nxpix Le 1 then begin
dprint, verbose=verbose, dlevel=4,'WARNING: Data segment ',strcompress(j,/remove_all),' is too small along the x-axis'
continue
endif else begin
no_color_scale=0
endelse
nx = n_elements(x1)
xp = findgen(nxpix)*(xcrange[1]-xcrange[0])/(nxpix-1) + xcrange[0]
xs = interp(findgen(nx),x1,xp )
if keyword_set(x_no_interp) then xs = round(xs)
image = interpolate(float(z1),xs,ys,missing = !values.f_nan,/grid)
endif else begin
nypix = round(scale*npy)
ny = dimen2(y1)
yp = findgen(nypix)*(ycrange[1]-ycrange[0])/(nypix-1) + ycrange[0]
nxpix = round(scale*npx)
if nxpix Le 1 then begin
dprint, verbose=verbose, dlevel=4,'WARNING: Data segment ',strcompress(j,/remove_all),' is too small along the x-axis'
continue
endif else begin
no_color_scale=0
endelse
nx = n_elements(x1)
xp = findgen(nxpix)*(xcrange[1]-xcrange[0])/(nxpix-1) + xcrange[0]
xs = interp(findgen(nx),x1,xp)
xs = xs # replicate(1.,nypix)
bad = where(finite(xs) eq 0,c)
if c ne 0 then xs[bad]=-1
if keyword_set(x_no_interp) then xs = round(xs)
ys = replicate(-1.,nxpix,nypix)
ny1 = dimen1(y1)
y_ind = findgen(ny)
xi = round(xs)
for i=0l,nxpix-1 do begin
m = (xi[i] > 0) < (ny1-1)
yt1 = reform(y1[m,*])
ys[i,*] = interp(y_ind,yt1,yp)
endfor
bad = where(finite(ys) eq 0,c)
if c ne 0 then ys[bad]=-1
if keyword_set(y_no_interp) then ys = round(ys)
image = interpolate(float(z1),xs,ys,missing = !values.f_nan)
endelse
if not keyword_set(gifplot) then begin
image = bytescale(image,bottom=bottom,top=top,range=zrange_new)
endif
str_element,opt,'fill_color',value=fill_color
if ~keyword_set(fill_color) then fill_color = -1
if fill_color ge 0 then begin
idx = where(image lt 255) & if idx[0] ne -1 then image[idx]=fill_color
no_color_scale = 1
endif
if xposition ge 0 and yposition ge 0 and xposition lt !d.x_size and yposition lt !d.y_size then begin
if fill_color lt 0 then begin
tv,image,xposition,yposition,xsize=npx,ysize=npy
endif else begin
idx = where( image eq fill_color )
if idx[0] ne -1 then begin
for i=0L, n_elements(idx)-1 do begin
ind = array_indices(image, idx[i] )
polyfill, xposition+ round( (ind[0]+[0,1,1,0])/scale ), $
yposition+ round( (ind[1]+[0,0,1,1])/scale ), color=fill_color, /device
endfor
endif
endelse
endif
str_element,/add,opt,'noerase',1
str_element,/add,opt,'overplot',/delete
str_element,/add,opt,'ytitle',/delete
str_element,/add,opt,'position',reform(transpose([[!x.window],[!y.window]]),4)
box,opt
endif else begin
msg = (npx le 0 and npy le 0) ? 'x/y' : (npx le 0) ? 'x':'y'
dprint, dlevel=3, 'Warning, data is outside the current '+msg+' axis range.'
endelse
endfor
str_element,opt,'constant',constant
if n_elements(constant) ne 0 then begin
str_element,opt,'const_color',const_color
if n_elements(const_color) ne 0 then ccols = get_colors(const_color) else ccols=!p.color
ncc = n_elements(constant)
for i=0,ncc-1 do $
oplot,opt.xrange,constant[i]*[1,1],color=ccols[i mod n_elements(ccols)],/linestyle
endif
zcharsize=!p.charsize
str_element,opt,'charsize',zcharsize
str_element,opt,'zcharsize',zcharsize
str_element,opt,'font',zfont
str_element,opt,'zfont',zfont
str_element,opt,'charthick',zcharthick
str_element,opt,'zcharthick',zcharthick
str_element,opt,'no_color_scale',no_color_scale
str_element,opt,'zposition',zposition
str_element,opt,'zoffset',zoffset
str_element,opt,'zminor',zminor
str_element,opt,'zgridstyle',zgridstyle
str_element,opt,'zthick',zthick
str_element,opt,'ztickformat',ztickformat
str_element,opt,'ztickinterval',ztickinterval
str_element,opt,'zticklayout',zticklayout
str_element,opt,'zticklen',zticklen
str_element,opt,'ztickname',ztickname
str_element,opt,'zticks',zticks
str_element,opt,'ztickunits',ztickunits
str_element,opt,'ztickv',ztickv
str_element,opt,'ztitle',ztitle
if not keyword_set(no_color_scale) then begin
if keyword_set(bottom) and keyword_set(top) then begin
draw_color_scale,brange=[bottom,top],range=zrange,log=zlog,title=ztitle, $
charsize=zcharsize,yticks=zticks,position=zposition,offset=zoffset,$
ygridstyle=zgridstyle,yminor=zminor,ythick=zthick,ytickformat=ztickformat,ytickinterval=ztickinterval,$
yticklayout=zticklayout,yticklen=zticklen,ytickname=ztickname,ytickunits=ztickunits,$
ytickv=ztickv,ytitle=ztitle,font=zfont,charthick=zcharthick
endif else begin
dprint, dlevel=0, 'Cannot draw color scale. Either the data is out of '+ $
'range or top/bottom options must be set in tplot.'
endelse
endif
x = xtemp
y = ytemp
z = ztemp
end