;+ ; NAME: ; PlotCurves ; PURPOSE: ; (Over)plot two arrays x, y. Connect only `valid' points. ; CALLING SEQUENCE: PRO PlotCurves, xin, yin, nvalid, $ sigma = sigma , $ xrange = xrange , $ yaxis = yaxis , $ ynozero = ynozero , $ ylog = ylog , $ yrange = yrange , $ ystyle = ystyle , $ ycolor = ycolor , $ color = color , $ changecolor = changecolor , $ nodata = nodata , $ markoutside = markoutside , $ _extra = _extra ; INPUTS: ; Input arguments passed to href=PlotPrep=: ; ; xin, yin abcissa and ordinate arrays; ; nvalid identifies the array elements to be plotted ; OPTIONAL INPUT PARAMETERS: ; Keywords passed to href=PlotPrep=: ; ; /oplotx if set, then overplot on plot set up by ; previous call to PlotCurves ; /newyaxis adds a new yaxis (if /oplot is NOT set, then /newaxis is assumed set) ; yaxis=yaxis controls the position of a new y axis ; ; /changecolor by default, bad data points are not plotted. ; If /changecolor is set bad points are connected with color[1] ; /nodata if set, only the x- and y-axes are drawn. Data points are ignored. ; (effectively this is just a call to PlotPrep). ; ; Additional keywords: ; ; sigma=sigma array; type: any ; must have same size as x,y. ; Standard deviations of y-data ; color=color scalar or array[2]; type: integer; default: [!p.color, !d.n_color-1] ; color indices used to connect points. ; color[0] is used to connect good data points ; color[1] is used to connect bad data points (if /changecolor is set) ; ycolor=ycolor scalar; type: integer; default: none ; passed to PlotPrep. Determines the color used to draw the y-axis. ; Useful to emphasize the association between y-axis and data points ; if multiple y-axes are used. ; markoutside=markoutside ; scalar, type: integer; default: 0 ; Can be used to make points outside the plot area visible ; by plotting an arrowhead pressed against the upper or lower ; x-axis. The value of markoutside determines the size of ; the arrowhead in device units. A negative value will turn ; the arrowhead into a solid triangle. The color is ; taken from the 'color' keyword. ; IDL plot keywords: ; ; xmargin, ymargin used only to start a new plot (/oplot NOT set) ; yrange, ynozero used only if new y-axis is plotted ; (/oplot NOT set, or /newaxis set) ; ynozero is NOT used if yrange is specified ; linestyle, xtitle, ytitle, psym, charsize ; INCLUDE: @compile_opt.pro ; On error, return to caller ; CALLS: ; InitVar ; RESTRICTIONS: ; There still seems to be a problem with the axis plotting: ; once a log axis has been plotted all added curves will also ; have a logarithmic scale, i.e. ylog=0 setting does not ; have any effect. This appears to be a bug in the IDL axis routine. ; PROCEDURE: ;> Only valid data points are connected by the type of line specified ; by the linestyle keyword. ;> Valid data points are identified in the nvalid array either by their ; array index or by a boolean value of 1. ; MODIFICATION HISTORY: ; APR-1996, Paul Hick (UCSD/CASS) ; OCT-1999, Paul Hick (UCSD/CASS) ; if nvalid is not specified only finite y-values (finite(y) = 1) are ; plotted, instead of all points ; FEB-2001, Paul Hick (UCSD/CASS) ; Fixed minor bug in handling of invalid data points. ; FEB-2004, Paul Hick (UCSD/CASS) ; Fixed bug for call with a time array as x-array when the time ; origin is not yet defined ; SEP-2007, Paul Hick (UCSD/CASS) ; Added keywords bar, hatch and shade for plotting bar graphs ; JUL-2008, Paul Hick (UCSD/CASS; pphick@ucsd.edu) ; Added xrange keyword ;- InitVar, changecolor, /key InitVar, nodata , /key n = PlotPrep( xin, yin, nvalid, $ xpnt = xpnt , $ ypnt = ypnt , $ npnt = npnt , $ yaxis = yaxis , $ xrange = xrange , $ yrange = yrange , $ ystyle = ystyle , $ ynozero = ynozero , $ ylog = ylog , $ ycolor = ycolor , $ changecolor = changecolor, $ _extra = _extra ) IF nodata THEN return goodcolor = !p.color badcolor = !d.n_colors/2 IF IsType(color,/defined) THEN BEGIN goodcolor = color[0] IF n_elements(color) GT 1 THEN badcolor = color[1] ENDIF nx = n_elements(xpnt) bsigma = n_elements(sigma) EQ nx m = 0 ; Add data points dlast = 0 ; Last good point? InitVar, markoutside, 0 IF markoutside NE 0 THEN BEGIN ddx = abs(float(markoutside))/!d.x_size/(!x.window[1]-!x.window[0])*(!x.crange[1]-!x.crange[0]) ddy = abs(float(markoutside))/!d.y_size/(!y.window[1]-!y.window[0])*(!y.crange[1]-!y.crange[0]) pnt_high = finite(ypnt) AND ypnt GT !y.crange[1] pnt_low = finite(ypnt) AND ypnt LT !y.crange[0] ENDIF WHILE m LT n DO BEGIN ; While there are points left to process ; Pick up next sequence of valid points ; There always is one point: npnt[m]. d = where ( npnt[m:n-1] EQ npnt[m]+indgen(n-m), i ) d = npnt[m+d] ; Indices of sequence of valid points ; d is a list of indices into x,y without gaps ; If there were invalid points between this sequence of valid ; points and the previous one, then plot them with badcolor if ; keyword /changecolor was set IF changecolor AND dlast NE d[0] THEN BEGIN oplot, [xpnt[dlast:d[0]]],[ypnt[dlast:d[0]]], $ color = badcolor , $ _extra = _extra IF bsigma THEN $ FOR j=dlast+1,d[0]-1 DO $ IF sigma[j] GT 0 THEN $ oplot, xpnt[j]*[1,1], ypnt[j]+sigma[j]*[-1,1], color=badcolor IF markoutside NE 0 THEN BEGIN FOR j=dlast+1,d[0]-1 DO BEGIN IF pnt_high[j] THEN BEGIN oplot, xpnt[j]+[-ddx,0,ddx,-ddx],!y.crange[1]+[-ddy,0,-ddy,-ddy],color=badcolor IF markoutside LT 0 THEN polyfill, xpnt[j]+[-ddx,0,ddx,-ddx],!y.crange[1]+[-ddy,0,-ddy,-ddy],color=badcolor ENDIF IF pnt_low [j] THEN BEGIN oplot, xpnt[j]+[-ddx,0,ddx,-ddx],!y.crange[0]+[ ddy,0, ddy, ddy],color=badcolor IF markoutside LT 0 THEN polyfill, xpnt[j]+[-ddx,0,ddx,-ddx],!y.crange[0]+[ ddy,0, ddy, ddy],color=badcolor ENDIF ENDFOR ENDIF ENDIF ; Plot the sequence of valid points oplot, [xpnt[d]],[ypnt[d]] , $ color = goodcolor , $ _extra = _extra IF bsigma THEN $ FOR j=d[0],d[i-1] DO $ IF sigma[j] GT 0 THEN $ oplot, xpnt[j]*[1,1], ypnt[j]+sigma[j]*[-1,1], color=goodcolor IF markoutside NE 0 THEN BEGIN FOR j=d[0],d[i-1] DO BEGIN IF pnt_high[j] THEN BEGIN oplot, xpnt[j]+[-ddx,0,ddx,-ddx],!y.crange[1]+[-ddy,0,-ddy,-ddy],color=goodcolor IF markoutside LT 0 THEN polyfill, xpnt[j]+[-ddx,0,ddx,-ddx],!y.crange[1]+[-ddy,0,-ddy,-ddy],color=goodcolor ENDIF IF pnt_low [j] THEN BEGIN oplot, xpnt[j]+[-ddx,0,ddx,-ddx],!y.crange[0]+[ ddy,0, ddy, ddy],color=goodcolor IF markoutside LT 0 THEN polyfill, xpnt[j]+[-ddx,0,ddx,-ddx],!y.crange[0]+[ ddy,0, ddy, ddy],color=goodcolor ENDIF ENDFOR ENDIF m += i dlast = d[i-1] ; Last good point ENDWHILE IF changecolor AND n NE 0 THEN BEGIN ; Still bad points left after last good point IF npnt[n-1] NE nx-1 THEN BEGIN oplot, [xpnt[npnt[n-1]:*]],[ypnt[npnt[n-1]:*]] , $ color = badcolor , $ _extra = _extra IF bsigma THEN $ FOR j=npnt[n-1]+1,nx-1 DO $ IF sigma[j] GT 0 THEN $ oplot, xpnt[j]*[1,1], ypnt[j]+sigma[j]*[-1,1], color=badcolor IF markoutside NE 0 THEN BEGIN FOR j=npnt[n-1]+1,nx-1 DO BEGIN IF pnt_high[j] THEN BEGIN oplot, xpnt[j]+[-ddx,0,ddx,-ddx],!y.crange[1]+[-ddy,0,-ddy,-ddy],color=badcolor IF markoutside LT 0 THEN polyfill, xpnt[j]+[-ddx,0,ddx,-ddx],!y.crange[1]+[-ddy,0,-ddy,-ddy],color=badcolor ENDIF IF pnt_low [j] THEN BEGIN oplot , xpnt[j]+[-ddx,0,ddx,-ddx],!y.crange[0]+[ ddy,0, ddy, ddy],color=badcolor IF markoutside LT 0 THEN polyfill, xpnt[j]+[-ddx,0,ddx,-ddx],!y.crange[0]+[ ddy,0, ddy, ddy],color=badcolor ENDIF ENDFOR ENDIF ENDIF ENDIF RETURN & END