;+ ; NAME: ; MPI_PLOT ; ; PURPOSE: ; ; This program is a simple wrapper for the IDL PLOT command. The ; main purpose of the program is to demonstrate one way the ; MPI_PLOTCONFIG program can be used to update plot parameters. ; ; AUTHOR: ; ; FANNING SOFTWARE CONSULTING ; David Fanning, Ph.D. ; 1645 Sheely Drive ; Fort Collins, CO 80526 USA ; Phone: 970-221-0438 ; E-mail: davidf@dfanning.com ; Coyote's Guide to IDL Programming: http://www.dfanning.com ; ; CATEGORY: ; ; Graphics ; ; CALLING SEQUENCE: ; ; MPI_Plot, x, y ; MPI_Plot, xx, yy, /Overplot ; ; INPUT PARAMETERS: ; ; x - The independent data. If y is not present, x is taken to be the dependent data. ; ; y - The dependent data. The vectors x and y must be the same length. ; ; xs - The independent data to overplot. If yy is not present, xx is taken to be the dependent data. ; ; yy - The dependent data to overplot. The vectors xx and yy must be the same length. ; ; INPUT KEYWORDS: ; ; BACKGROUND - The name of a background color. (See below for a list of color names.) ; By default on 24-bit systems: 'IVORY'. Uses 'GRAY' on 8-bit systems. ; ; COLOR - The name of the plot color. (See below for a list of color names.) ; By default on 24-bit systems: 'SADDLE BROWN'. Uses 'GREEN' on 8-bit systems. ; When OVERPLOTing, use the COLOR keyword to specify the color of the overplot. ; ; DATACOLOR - The name of the data color. By default the same as the COLOR keyword. ; (See below for a list of color names.) When OVERPLOTing, use the COLOR keyword ; to specify the color of the overplot. ; ; OVERPLOT - Set this keyword to overplot data into the MPI_PLOT window. ; If multiple windows are on the display, select the one to overplot into ; by selecting it with the cursor. ; ; PSYM - The plot symbol value. By default, 18. Possible values are: ; 0 - Dot ; 1 - Filled Circle ; 2 - Filled Upward Triangle ; 3 - Filled Downward Triangle ; 4 - Filled Diamond ; 5 - Filled Square ; 6 - Open Circle ; 7 - Open Upward Triangle ; 8 - Open Downward Triangle ; 9 - Open Diamond ; 10 - Open Square ; 11 - Plus Sign ; 12 - X ; 13 - Star ; 14 - Filed Rightfacing Triangle ; 15 - Filled Leftfacing Triangle ; 16 - Open Rightfacing Triangle ; 17 - Open Leftfacing Triangle ; 18 - No Symbol (the default). ; ; TITLE - The title of the plot. By default, a null string. ; ; XLOG = Set this keyword to use logarithmic axis styling on the X axis. ; ; XTITLE - The title of the X axis of the plot. By default, a null string. ; ; YLOG = Set this keyword to use logarithmic axis styling on the Y axis. ; ; YTITLE - The title of the Y axis of the plot. By default, a null string. ; ; In addition, any keyword appropriate for the MPI_PLOTCONFIG object program can be used. ; Among those keywords, are these most popular ones: ; ; CHARSIZE - The character size of the plot. By default, 1.0. ; ; CHARTHICK - The character thickness of the plot. By default, 1.0. ; ; FONT - The type of plot font: -1=Hershey, 0=Hardware, 1=True-Type. By default, !P.FONT. ; ; LINESTYLE - The plot linestyle. By default, 0. Possible values are: ; 0 - Solid Line ; 1 - Dotted ; 2 - Dashed ; 3 - Dash Dot ; 4 - Dash Dot Dot ; 5 - Long Dash ; 6 - No Line ; ; POSITION - The position of the plot in the plot window in normalized coordinates. By default, [0.20, 0.15, 0.95, 0.95]. ; ; SYMSIZE - The plot symbol size. By default, 1.0. ; ; THICK - The plot line thickness. By default, 1.0. ; ; TICKLEN - The plot tick length. By default, 0.02. ; ; COLOR NAMES: ; ; The following color names can be used for BACKGROUND, COLOR and DATACOLOR keywords: ; ; White, Snow, Ivory, Light Yellow, Cornsilk, Beige, Seashell, Linen, Antique White, ; Papaya, Almond, Bisque, Moccasin, Wheat, Burlywood, Tan, Light Gray, Lavender, ; Medium Gray, Gray, Slate Gray, Dark Gray , Charcoal, Black, Light Cyan, Powder Blue, ; Sky Blue, Steel Blue, Dodger Blue, Royal Blue, Blue, Navy, Honeydew, Pale Green, ; Aquamarine, Spring Green, Cyan, Turquoise, Sea Green, Forest Green, Green Yellow, ; Chartreuse, Lawn Green, Green, Lime Green, Olive Drab, Olive, Dark Green, Pale Goldenrod, ; Khaki, Dark Khaki, Yellow, Gold, Goldenrod, Dark Goldenrod, Saddle Brown, Rose, ; Pink, Rosy Brown, Sandy Brown, Peru, Indian Red, Chocolate, Sienna, Dark Salmon, ; Salmon, Light Salmon, Orange, Coral, Light Coral, Firebrick, Brown, Hot Pink, ; Deep Pink, Magenta, Tomato, Orange Red, Red, Violet Red, Maroon, Thistle, Plum, ; Violet, Orchid, Medium Orchid, Dark Orchid, Blue Violet, and Purple. ; ; REQUIRED PROGRAMS: ; ; The following programs are required to reside in your !PATH. They can be ; obtained from the Coyote Library: ; ; http://www.dfanning.com/programs/adjustposition.pro ; http://www.dfanning.com/programs/cw_drawcolor.pro ; http://www.dfanning.com/programs/cw_spacer.pro ; http://www.dfanning.com/programs/error_message.pro ; http://www.dfanning.com/programs/fsc_color.pro ; http://www.dfanning.com/programs/fsc_droplist.pro ; http://www.dfanning.com/programs/fsc_field.pro ; http://www.dfanning.com/programs/fsc_fileselect.pro ; http://www.dfanning.com/programs/fsc_inputfield.pro ; http://www.dfanning.com/programs/fsc_psconfig__define.pro ; http://www.dfanning.com/programs/mpi_plotconfig__define.pro ; http://www.dfanning.com/programs/mpi_axis.pro ; http://www.dfanning.com/programs/mpi_axis__define.pro ; http://www.dfanning.com/programs/pickcolorname.pro ; http://www.dfanning.com/programs/psconfig.pro ; http://www.dfanning.com/programs/pswindow.pro ; http://www.dfanning.com/programs/tvread.pro ; ; All these programs can be obtained at once by downloading the MPI_PLOT zip file: ; ; http://www.dfanning.com/programs/mpi_plot.zip ; ; ; COMMON BLOCK: ; ; The addition of the OVERPLOT keyword required a COMMON block named MPI_PLOT_COMMMON ; to store the program information pointer. This pointer is loaded in the COMMON block ; when the keyboard focus changes. Thus, to overplot into an MPI_PLOT window, first ; select the window with the cursor. ; ; RESTRICTIONS ; ; Colors will be loaded in the color table. ; ; EXAMPLE: ; ; x = Findgen(11) & y = Findgen(11) ; MPI_PLOT, x, y ; MPT_PLOT, Reverse(x), y, /Overplot, Linestyle=2 ; ; MODIFICATION HISTORY: ; ; Written by David W. Fanning, March 2001, and offered to the IDL user ; community by the Max-Plank Institute of Meteorology in Hamburg, Germany. ; Added OVERPLOT keyword and made numerous general improvements. 21 November 2001. DWF ; Removed restriction for only one copy of MPI_PLOT on display at once. 25 November 2001. DWF. ; Added XLOG and YLOG keywords. 7 May 2002. DWF. ; PostScript configuration now opens up with a plot window the same aspect ; ratio as the MPI_PLOT window. 21 August 2002. DWF. ;- ; ;########################################################################### ; ; LICENSE ; ; This software is OSI Certified Open Source Software. ; OSI Certified is a certification mark of the Open Source Initiative. ; ; Copyright © 2000-2002 Fanning Software Consulting. ; ; This software is provided "as-is", without any express or ; implied warranty. In no event will the authors be held liable ; for any damages arising from the use of this software. ; ; Permission is granted to anyone to use this software for any ; purpose, including commercial applications, and to alter it and ; redistribute it freely, subject to the following restrictions: ; ; 1. The origin of this software must not be misrepresented; you must ; not claim you wrote the original software. If you use this software ; in a product, an acknowledgment in the product documentation ; would be appreciated, but is not required. ; ; 2. Altered source versions must be plainly marked as such, and must ; not be misrepresented as being the original software. ; ; 3. This notice may not be removed or altered from any source distribution. ; ; For more information on Open Source Software, visit the Open Source ; web site: http://www.opensource.org. ; ;########################################################################### PRO MPI_Overplot__Define struct = { MPI_OVERPLOT, $ ; The overplot structure. dep: Ptr_New(), $ ; The dependent data. indep: Ptr_New(), $ ; The independent data. extra: Ptr_New(), $ ; Any extra keywords. color: "", $ ; The name of the overplot color. psym:0L $ ; The symbol used for overplotting. } END; ------------------------------------------------------------------------- PRO MPI_Plot_DrawThePlot, infoptr, Overplot=overplot ; This procedure draws the plot and overplot on the ; output device. ; Error handling. Catch, theError IF theError NE 0 THEN BEGIN Catch, /cancel ok = Error_Message(/Traceback) ENDIF ; Set current graphics window for devices that support it. IF (!D.Flags AND 256) NE 0 THEN WSet, (*infoptr).wid ; Restore plotting and axis system variables. Required for overplotting. !X = (*infoptr).x !Y = (*infoptr).y !P = (*infoptr).p ; Draw the plot. IF Keyword_Set(overplot) EQ 0 THEN BEGIN plotkeywords = (*infoptr).plotconfig->GetKeywords() IF (!D.Flags AND 256) EQ 0 THEN BEGIN PolyFill, [0, 0, 1, 1, 0], [0, 1, 1, 0, 0], /Normal, Color=plotkeywords.background Plot, (*infoptr).indep, (*infoptr).dep, _Extra=plotkeywords, /NoData, /NoErase ENDIF ELSE BEGIN Plot, (*infoptr).indep, (*infoptr).dep, _Extra=plotkeywords, /NoData ENDELSE plotkeywords.color = plotkeywords.datacolor OPlot, (*infoptr).indep, (*infoptr).dep, _Extra=plotkeywords ENDIF ; Draw any overplots. IF Ptr_Valid((*infoptr).oplotinfo) THEN BEGIN FOR j=0,N_Elements(*(*infoptr).oplotinfo)-1 DO BEGIN struct = (*(*infoptr).oplotinfo)[j] OPlot, *struct.indep, *struct.dep, _Extra=*struct.extra, $ Color=FSC_Color(struct.color, !D.Table_Size-4+j), $ PSym=(*infoptr).plotconfig->Symbol(struct.psym) ENDFOR ENDIF ; Update the system variables. (*infoptr).x = !X (*infoptr).y = !Y (*infoptr).p = !P END; ------------------------------------------------------------------------- PRO MPI_Plot_Clear_Overplots, event ; This procedure clears any overplots from the program. ; Get info structure. Widget_Control, event.top, Get_UValue=infoptr ; Free the overplot pointer. IF Ptr_Valid((*infoptr).oplotinfo) THEN BEGIN FOR j=0,N_Elements(*(*infoptr).oplotinfo)-1 DO BEGIN struct = (*(*infoptr).oplotinfo)[j] Ptr_Free, struct.dep Ptr_Free, struct.indep Ptr_Free, struct.extra ENDFOR Ptr_Free, (*infoptr).oplotinfo ENDIF ELSE Ptr_Free, (*infoptr).oplotinfo ; Turn overplot button off. Widget_Control, (*infoptr).clearoplotID, Sensitive=0 ; Redraw the plot. MPI_Plot_DrawThePlot, infoptr END; ------------------------------------------------------------------------- PRO MPI_Plot_PostScript, event ; This event handler creates PostScript output. ; Get info structure. Widget_Control, event.top, Get_UValue=infoptr ; Make the display window current. WSet, (*infoptr).wid keywords = PSWindow() pskeywords = PSConfig(Cancel=cancelled, _Extra=keywords) IF cancelled THEN RETURN ; Configure the PostScript device. thisDevice = !D.Name Set_Plot, 'PS' Device, _Extra=pskeywords ; Display the grapics. Background color will have to be done ; separately. And if color is turned off, we have have to do ; things differntly, too. plotkeywords = (*infoptr).plotconfig->GetKeywords() IF pskeywords.color EQ 1 THEN BEGIN PolyFill, [0, 0, 1, 1, 0], [0, 1, 1, 0, 0], /Normal, Color=plotkeywords.background Plot, (*infoptr).indep, (*infoptr).dep, _Extra=plotkeywords, /NoData, /NoErase plotkeywords.color = plotkeywords.datacolor OPlot, (*infoptr).indep, (*infoptr).dep, _Extra=plotkeywords ENDIF ELSE BEGIN plotkeywords.color = !P.Color plotkeywords.datacolor = !P.Color plotkeywords.background = !P.Background Plot, (*infoptr).indep, (*infoptr).dep, _Extra=plotkeywords, /NoData OPlot, (*infoptr).indep, (*infoptr).dep, _Extra=plotkeywords ENDELSE ; Any overplotting to do? IF Ptr_Valid((*infoptr).oplotinfo) THEN BEGIN FOR j=0,N_Elements(*(*infoptr).oplotinfo)-1 DO BEGIN struct = (*(*infoptr).oplotinfo)[j] OPlot, *struct.indep, *struct.dep, _Extra=*struct.extra, $ Color=FSC_Color(struct.color, !D.Table_Size-4+j), $ PSym=(*infoptr).plotconfig->Symbol(struct.psym) ENDFOR ENDIF ; Close the PostScript file and clean up. Device, /Close_File Set_Plot, thisDevice END; ------------------------------------------------------------------------- PRO MPI_Plot_Print, event ; This event handler executes the command in the Printer device. ; Set up the printer. ok = Dialog_PrinterSetup() IF NOT ok THEN RETURN ; Get info structure and printer orientation. Widget_Control, event.top, Get_UValue=infoptr Widget_Control, event.id, Get_UValue=orientation ; Save the current graphics device. thisDevice = !D.Name ; Make the display window current. WSet, (*infoptr).wid ; With printers, you have to load your drawing colors ; *before* you enter the PRINTER device and then copy ; them into the device. It's a pain in the ol' wazoo, ; but there is no help for it. :-( plotkeywords = (*infoptr).plotconfig->GetKeywords() TVLCT, FSC_Color(plotkeywords.name_background, /Triple), !P.Background TVLCT, FSC_Color(plotkeywords.name_color, /Triple), !D.Table_Size-2 TVLCT, FSC_Color(plotkeywords.name_datacolor, /Triple), !D.Table_Size-3 IF Ptr_Valid((*infoptr).oplotinfo) THEN BEGIN FOR j=0,N_Elements(*(*infoptr).oplotinfo)-1 DO BEGIN struct = (*(*infoptr).oplotinfo)[j] TVLCT, FSC_Color(struct.color, /Triple),!D.Table_Size-4+j ENDFOR ENDIF ; Set up the printer. You may have to adjust the fudge factors ; to account for the printable area offset. CASE orientation OF 'PORTRAIT': BEGIN keywords = PSWindow(/Printer, Fudge=0.25) Set_Plot, 'PRINTER', /Copy Device, Portrait=1 ENDCASE 'LANDSCAPE': BEGIN keywords = PSWindow(/Printer, /Landscape, Fudge=0.25) Set_Plot, 'PRINTER', /Copy Device, Landscape=1 ENDCASE ENDCASE Device, _Extra=keywords ; Display the graphics. MPI_Plot_DrawThePlot, infoptr ; Close the printer file and clean up. Device, /Close_Document Set_Plot, thisDevice END ;---------------------------------------------------------------------------------------- PRO MPI_Plot_SaveAs, event ; Saves the current display window as output files. ; Get the info structure and the appropriate file extension. Widget_Control, event.top, Get_UValue=infoptr Widget_Control, event.id, Get_UValue=file_extension ; Base name for file output. basename = 'mpi_plot' ; Take a snapshot of the display window and write the file. WSet, (*infoptr).wid CASE file_extension OF 'BMP' : image = TVREAD(Filename = basename, /BMP) 'GIF' : image = TVREAD(Filename = basename, /GIF) 'PICT' : image = TVREAD(Filename = basename, /PICT) 'JPG' : image = TVREAD(Filename = basename, /JPEG) 'TIF' : image = TVREAD(Filename = basename, /TIFF) 'PNG' : image = TVREAD(Filename = basename, /PNG) ENDCASE END ;---------------------------------------------------------------------------------------- PRO MPI_Plot_Quit, event Widget_Control, event.top, /Destroy END ;----------------------------------------------------------------------------- PRO MPI_Plot_Cleanup, tlb ; This is the cleanup routine for the program. All ; created objects and pointers must be destroyed. Widget_Control, tlb, Get_UValue=infoptr Obj_Destroy, (*infoptr).xaxis Obj_Destroy, (*infoptr).yaxis Obj_Destroy, (*infoptr).plotconfig IF Ptr_Valid((*infoptr).oplotinfo) THEN BEGIN FOR j=0,N_Elements(*(*infoptr).oplotinfo)-1 DO BEGIN struct = (*(*infoptr).oplotinfo)[j] Ptr_Free, struct.dep Ptr_Free, struct.indep Ptr_Free, struct.extra ENDFOR Ptr_Free, (*infoptr).oplotinfo ENDIF ELSE Ptr_Free, (*infoptr).oplotinfo Ptr_Free, infoptr END ;----------------------------------------------------------------------------- PRO MPI_Plot_Configure_Button, event ; This event handler responds to requests to configure the ; plot parameters. Events will be sent to the buttonbase widget. Widget_Control, event.top, Get_UValue=infoptr ; Call the GUI method on the Plot Configuration object. Widget_Control, event.top, Update=0 (*infoptr).plotconfig->GUI, Group_Leader=event.top, All_Events=1, $ NotifyID=[(*infoptr).buttonbase, event.top] Widget_Control, event.top, Update=1 END ;----------------------------------------------------------------------------- PRO MPI_Plot_Resize, event thisEvent = Tag_Names(event, /Structure_Name) IF thisEvent EQ 'WIDGET_BASE' THEN BEGIN ; This event handler responds to TLB re-size events. Widget_Control, event.top, Get_UValue=infoptr ; Make the display window the current graphics window. WSet, (*infoptr).wid ; Resize the draw widget. Widget_Control, (*infoptr).drawID, Draw_XSize=(*infoptr).xminsize > event.x, $ Draw_YSize=event.y - (*infoptr).ysize ; Display the graphics. MPI_Plot_DrawThePlot, infoptr RETURN ENDIF IF thisEvent EQ 'WIDGET_KBRD_FOCUS' THEN BEGIN ; This event handler responds to TLB keyboard focus events. IF event.enter EQ 0 THEN RETURN ; Declare the common block with the info pointer. COMMON MPI_PLOT_COMMON, thePointer Widget_Control, event.top, Get_UValue=infoptr ; Make the display window the current graphics window. WSet, (*infoptr).wid ; Set the pointer to the common block. thePointer = infoptr RETURN ENDIF END ;----------------------------------------------------------------------------- PRO MPI_Plot_Configuration_Events, event ; This event handler responds to events comimg from ; the Plot Configuration widget via the buttonbase widget. Catch, theError IF theError NE 0 THEN BEGIN Catch, /cancel ok = Error_Message(/Rraceback) ENDIF Widget_Control, event.top, Get_UValue=infoptr ; Display the graphics. MPI_Plot_DrawThePlot, infoptr END ;----------------------------------------------------------------------------- PRO MPI_Plot, x, y, _Extra=extra, XTitle=xtitle, YTitle=ytitle, Title=title, $ Overplot=overplot, Color=color, DataColor=datacolor, PSym=psym, XLog=xlog, $ YLog=ylog ; Error handling. Catch, theError IF theError NE 0 THEN BEGIN Catch, /Cancel ok = Error_Message(/Traceback) RETURN ENDIF ; Common block required for overplotting capability. COMMON MPI_PLOT_COMMON, infoPtr ; Check color keywords. Differences for display depth ; and overplotting verses plotting. Device, Get_Visual_Depth=theDepth IF theDepth GT 8 THEN BEGIN IF Keyword_Set(overplot) THEN BEGIN IF N_Elements(color) EQ 0 THEN BEGIN IF Ptr_Valid(infoptr) THEN BEGIN plotkeywords = (*infoptr).plotconfig->GetKeywords() color = plotkeywords.name_datacolor ENDIF ELSE color = 'SADDLE BROWN' ENDIF ENDIF ELSE BEGIN IF N_Elements(background) EQ 0 THEN background = 'IVORY' IF N_Elements(color) EQ 0 THEN color = 'SADDLE BROWN' IF N_Elements(datacolor) EQ 0 THEN datacolor = color ENDELSE ENDIF ELSE BEGIN IF Keyword_Set(overplot) THEN BEGIN IF N_Elements(color) EQ 0 THEN BEGIN IF Ptr_Valid(infoptr) THEN BEGIN plotkeywords = (*infoptr).plotconfig->GetKeywords() color = plotkeywords.name_datacolor ENDIF ELSE color = 'GREEN' ENDIF ENDIF ELSE BEGIN IF N_Elements(background) EQ 0 THEN background = 'GRAY' IF N_Elements(color) EQ 0 THEN color = 'GREEN' IF N_Elements(datacolor) EQ 0 THEN datacolor = color ENDELSE ENDELSE ; Make sure color names are strings. IF N_Elements(psym) EQ 0 THEN psym = 18 ; No symbol. ; Are you overplotting something? IF Keyword_Set(overplot) EQ 0 THEN BEGIN ; Do we have the color right? IF Size(color, /TName) NE 'STRING' THEN Message, 'COLOR must be specified as color NAME.', /NoName ; Because of common block, only one MPI_PLOT at a time allowed. ; IF XRegistered('mpi_plot') GT 0 THEN BEGIN ; ok = Dialog_Message('Only one MPI_PLOT can be used at once. Try overplotting.') ; RETURN ; ENDIF infoPtr = Ptr_New() ENDIF ELSE BEGIN ; Is there a current plot? IF Ptr_Valid(infoptr) EQ 0 THEN BEGIN ok = Dialog_Message('There is no current plot to overplot onto. Returning.') RETURN ENDIF ; Sort out the positional parameters. IF N_Elements(x) EQ 0 THEN BEGIN ok = Dialog_Message('Please supply data for overplotting.') RETURN ENDIF ELSE BEGIN IF N_Elements(y) EQ 0 THEN BEGIN dep = x indep = Indgen(N_Elements(x)) ENDIF ELSE BEGIN dep = y indep = x ENDELSE ENDELSE ; Create an overplot structure and add it to the info structure. struct = {MPI_OVERPLOT, Ptr_New(dep), Ptr_New(indep), Ptr_New(extra), color:color, psym:psym} IF Ptr_Valid((*infoptr).oplotinfo) THEN $ *(*infoptr).oplotinfo = [*((*infoptr).oplotinfo), struct] ELSE $ (*infoptr).oplotinfo = Ptr_New([struct]) ; Draw the plot. MPI_Plot_DrawthePlot, infoptr, /Overplot ; Allow the clear oplots button to be active. Widget_Control, (*infoptr).clearoplotID, Sensitive=1 RETURN ENDELSE ; Sort out the positional parameters for plotting. IF N_Elements(x) EQ 0 THEN BEGIN x = Findgen(101) dep = Sin(x/5)/ Exp(x/50) Indep = Findgen(101) ENDIF ELSE BEGIN IF N_Elements(y) EQ 0 THEN BEGIN dep = x indep = Indgen(N_Elements(x)) ENDIF ELSE BEGIN dep = y indep = x ENDELSE ENDELSE ; Check keywords. IF N_Elements(title) EQ 0 THEN title="" IF N_Elements(xtitle) EQ 0 THEN xtitle="" IF N_Elements(ytitle) EQ 0 THEN ytitle="" IF Size(background, /TName) NE 'STRING' THEN Message, 'BACKGROUND must be specified as color NAME.', /NoName IF Size(color, /TName) NE 'STRING' THEN Message, 'COLOR must be specified as color NAME.', /NoName IF Size(datacolor, /TName) NE 'STRING' THEN Message, 'DATACOLOR must be specified as color NAME.', /NoName ; Check for availability of GIF files. thisVersion = Float(!Version.Release) IF thisVersion LT 5.4 THEN haveGif = 1 ELSE haveGIF = 0 ; Find the data axes ranges. mindep = Min(dep, Max=maxdep) minindep = Min(indep, Max=maxindep) ; Create the widgets. tlb = Widget_Base(Column=1, TLB_Size_Events=1, Base_Align_Center=1, Title='MPI_Plot', KBRD_Focus_Events=1) drawid = Widget_Draw(tlb, XSize=400, YSize=400) buttonbase = Widget_Base(tlb, Row=1) ; Quit button. button = Widget_Button(buttonbase, Value='Quit', Event_Pro='MPI_Plot_Quit', /Dynamic_Resize) ; Print button. printID = Widget_Button(buttonbase, Value='Print', Event_Pro='MPI_Plot_Print', /Menu, /Dynamic_Resize) dummy = Widget_Button(printID, Value='Landscape Orientation', UVALUE='LANDSCAPE') dummy = Widget_Button(printID, Value='Portrait Orientation', UVALUE='PORTRAIT') ; Save As button. saveID = Widget_Button(buttonbase, Value='Save As', Event_Pro='MPI_Plot_SaveAs', /Menu, /Dynamic_Resize) dummy = Widget_Button(saveID, Value='BMP File', UValue='BMP') IF havegif THEN dummy = Widget_Button(saveID, Value='GIF File', UValue='GIF') dummy = Widget_Button(saveID, Value='PICT File', UValue='PICT') dummy = Widget_Button(saveID, Value='PNG File', UValue='PNG') dummy = Widget_Button(saveID, Value='JPEG File', UValue='JPG') dummy = Widget_Button(saveID, Value='TIFF File', UValue='TIF') psID = Widget_Button(saveID, Value="PostScript File", UValue='PS', $ Event_Pro='MPI_Plot_Postscript') ; Clear overplots. clearoplotID = Widget_Button(buttonbase, Value='Clear Overplots', $ Event_Pro='MPI_Plot_Clear_Overplots', /Dynamic_Resize, Sensitive=0) ; Modify Plot button. button = Widget_Button(buttonbase, Value='Modify Plot', $ Event_Pro='MPI_Plot_Configure_Button', /Dynamic_Resize) ; Set up a widget to receive the Plot Configuration Events. The ; Buttonbase is not being used currently, so is a good choice. Widget_Control, buttonBase, Event_Pro='MPI_Plot_Configuration_Events' ; Create the axis and plot configuration objects. xaxis = Obj_New("MPI_Axis", Range=[minindep, maxindep], /XAxis, _Extra=extra, Title=xtitle, $ Log=Keyword_Set(xlog)) yaxis = Obj_New("MPI_Axis", Range=[mindep, maxdep], /YAxis, _Extra=extra, Title=ytitle, $ Log=Keyword_Set(ylog)) plotconfig=Obj_New("MPI_PlotConfig", XAxis=xaxis, YAxis=yaxis, _Extra=extra, $ Title=title, Color=color, DataColor=datacolor, Background=background, PSym=psym, $ UseDataColor=1) ; Realize the program and make the display window the current graphics window. Widget_Control, tlb, /Realize, Update=0 Widget_Control, drawid, Get_Value=wid ; Draw the plot. WSet, wid plotkeywords = plotconfig->GetKeywords() Plot, indep, dep, _Extra=plotkeywords, /NoData plotkeywords.color = plotkeywords.datacolor OPlot, indep, dep, _Extra=plotkeywords Widget_Control, tlb, Update=1 ; Inquire about buttonbase sizes. Needed for resizing events. geom = Widget_Info(buttonbase, /Geometry) ysize = geom.scr_ysize + 10 xminsize = geom.scr_xsize ; Create an info structure and store it in the UValue of the TLB. info = {xaxis:xaxis, yaxis:yaxis, wid:wid, dep:dep, indep:indep, plotconfig:plotconfig, $ buttonbase:buttonbase, drawid:drawid, ysize:ysize, xminsize:xminsize, oplotinfo:Ptr_New(), $ x:!X, y:!Y, p:!p, clearoplotID:clearoplotID} infoPtr = Ptr_New(info, /No_Copy) Widget_Control, tlb, set_uvalue=infoPtr XManager, 'mpi_plot', tlb, /No_Block, Cleanup='MPI_Plot_Cleanup', $ Event_Handler='MPI_Plot_Resize' END