📄 multiplot.pro
字号:
; number of plots left in the grid if n_elements(nleft) eq 1 then init = (nleft eq 0) else init = 1 if (n_elements(pmulti) eq 2) or (n_elements(pmulti) eq 5) then init = 1 if (n_elements(!p.multi) eq 5) then begin if (!p.multi[1] gt 0) and (!p.multi[2] gt 0) then begin init = (!p.multi[0] eq 0) endif endif ; initialize if we are on the first plot if init or keyword_set(initialize) then begin case n_elements(pmulti) of 0:begin if n_elements(!p.multi) eq 1 then return ; NOTHING TO SET if n_elements(!p.multi) ne 5 then begin message,'Bogus !p.multi; aborting.' endif nplots = !p.multi[1:2] > 1 if keyword_set(rowmajor) then begin colmajor = 0 endif else begin colmajor = !p.multi[4] eq 0 endelse end 2:begin nplots = pmulti colmajor = not keyword_set(rowmajor) end 5:begin nplots = pmulti[1:2] if keyword_set(rowmajor) then begin colmajor = 0 endif else begin colmajor = pmulti[4] eq 0 endelse end else: message,'pmulti can only have 0, 2, or 5 elements.' endcase pposition = !p.position ; save sysvar to be altered xtickname = !x.tickname ytickname = !y.tickname ; keep original values for resetting xtickformat_orig = !x.tickformat ytickformat_orig = !y.tickformat ; what will we actually plot when ticks are exposed? if n_elements(xtickformat_in) ne 0 then begin xtickformat=xtickformat_in endif else begin xtickformat=xtickformat_orig endelse if n_elements(ytickformat_in) ne 0 then begin ytickformat=ytickformat_in endif else begin ytickformat=ytickformat_orig endelse pdotmulti = !p.multi nleft = nplots[0]*nplots[1] ; total # of plots !p.position = 0 ; reset !p.multi = 0 ; set window & region plot,/nodata,xstyle=4,ystyle=4,!x.range,!y.range,/noerase px = !x.window*!d.x_vsize py = !y.window*!d.y_vsize xsize = px[1] - px[0] ysize = py[1] - py[0] ; in normlized coordinates nmargins = [min(!x.window)-min(!x.region), $ min(!y.window)-min(!y.region), $ max(!x.region)-max(!x.window), $ max(!y.region)-max(!y.window)] ;in device coord margins = nmargins margins[0] = nmargins[0]*!d.x_vsize margins[2] = nmargins[2]*!d.x_vsize margins[1] = nmargins[1]*!d.y_vsize margins[3] = nmargins[3]*!d.y_vsize noerase = !p.noerase !p.noerase = 1 ; !p.multi does the same if keyword_set(verbose) then begin major = ['across then down (column major).',$ 'down then across (row major).'] if colmajor then index = 0 else index = 1 message,/inform,'Initialized for '+strtrim(nplots[0],2) $ +'x'+strtrim(nplots[1],2)+', plotted '+major[index] endif if keyword_set(initialize) then return endif ; ; Define the plot region without using !p.multi. ; cols = nplots[0] ; for convenience rows = nplots[1] nleft = nleft - 1 ; decrement plots remaining cur = cols*rows - nleft ; current plot #: 1 to cols*rows ; device coords per plot idx = [(!d.x_vsize-margins[0]-margins[2])/cols, $ (!d.y_vsize-margins[1]-margins[3])/rows] ;; force to be square if requested if sqplot then begin if idx[0] lt idx[1] then idx[1]=idx[0] else idx[0]=idx[1] endif if colmajor then begin ; location in matrix of plots col = cur mod cols if col eq 0 then col = cols row = (cur-1)/cols + 1 endif else begin ; here (1,2) is 1st col, 2nd row row = cur mod rows if row eq 0 then row = rows col = (cur-1)/rows + 1 endelse pos = $ [(col-1)*idx[0], (rows-row)*idx[1], $ col*idx[0], (rows-row+1)*idx[1]] $ + $ [margins[0], margins[1], $ margins[0], margins[1]] ; back to normalized coords pos[0] = pos[0]/!d.x_vsize pos[2] = pos[2]/!d.x_vsize pos[1] = pos[1]/!d.y_vsize pos[3] = pos[3]/!d.y_vsize ; add gaps pos[0] = pos[0] + xgap pos[2] = pos[2] - xgap pos[1] = pos[1] + ygap pos[3] = pos[3] - ygap ; ; Finally set the system variables; user shouldn't change them. ; !p.position = pos onbottom = (row eq rows) or (rows eq 1) onleft = (col eq 1) or (cols eq 1) IF keyword_set(doxaxis) THEN onbottom=1 IF keyword_set(doyaxis) THEN onleft=1 if onbottom then begin !x.tickname = xtickname endif else begin !x.tickname = replicate(' ',30) endelse if onleft then !y.tickname = ytickname else !y.tickname = replicate(' ',30) if onbottom then !x.tickformat = xtickformat else !x.tickformat = '' if onleft then !y.tickformat = ytickformat else !y.tickformat = '' if keyword_set(verbose) then begin coords = '['+string(pos,form='(3(f4.2,","),f4.2)')+']' plotno = 'Setup for plot ['+strtrim(col,2)+','+strtrim(row,2)+'] of ' $ +strtrim(cols,2)+'x'+strtrim(rows,2) message,/inform,plotno+' at '+coords endif ; Add titles to overall axes ; area covered by entire plot field in device coords allpos = $ [0, 0, cols*idx[0], rows*idx[1]] + $ [margins[0], margins[1], margins[0], margins[1]] ;; back to normalized coords allpos[0] = allpos[0]/!d.x_vsize allpos[2] = allpos[2]/!d.x_vsize allpos[1] = allpos[1]/!d.y_vsize allpos[3] = allpos[3]/!d.y_vsize xCharSizeNorm = float(!d.x_ch_size) / float(!d.x_size) yCharSizeNorm = float(!d.y_ch_size) / float(!d.y_size) ; top title if n_elements(mTitle) ne 0 then begin if n_elements(mTitSize) eq 0 then mTitSize = 1.0 if n_elements(mTitOffset) eq 0 then mTitOffset = 0.0 ; align middle of region in x xpos = (allpos[2] - allpos[0])/2.0 + nmargins[0] ; align relative to the top. Default is right there plus ; one character size. ypos = allpos[3] + (mTitOffset+1.0)*yCharSizeNorm ; correct for gaps ypos = ypos - ygap xyouts, $ xpos, $ ypos, $ mTitle, $ /normal, $ align = 0.5, $ charsize = 1.25 * mTitSize endif ; x title if n_elements(mxTitle) ne 0 then begin if n_elements(mxTitSize) eq 0 then mxTitSize = 1.0 if n_elements(mxTitOffset) eq 0 then mxTitOffset = 0.0 ; align middle of region in x xpos = (allpos[2] - allpos[0])/2.0 + nmargins[0] ; align middle of region in x ypos = allpos[1] - (mxTitOffset+3.0)*yCharSizeNorm ; correct for gaps ypos = ypos + ygap xyouts, $ xpos, $ ypos, $ mxTitle, $ /normal, $ align = 0.5, $ charsize = mxTitSize endif ; y title if n_elements(myTitle) ne 0 then begin if n_elements(myTitSize) eq 0 then myTitSize = 1.0 if n_elements(myTitOffset) eq 0 then myTitOffset = 0.0 ; align relative to the left side. Default is right there plus ; one character size. xpos = allpos[0] - (myTitOffset+6.0)*xCharSizeNorm ;xpos = allpos[0] - (myTitOffset+4.0)*xCharSizeNorm ; align middle of region in x ypos = (allpos[3] - allpos[1])/2.0 + nmargins[1] ; correct for gaps xpos = xpos + xgap xyouts, $ xpos, $ ypos, $ myTitle, $ /normal, $ align = 0.5, $ orientation = 90.0, $ charsize = myTitSize endifreturnend
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -