爱气象,爱气象家园! 

气象家园

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 9399|回复: 11

[作图] 求优化一段程序,画一个图得几个小时

[复制链接]
发表于 2015-5-5 22:16:30 | 显示全部楼层 |阅读模式

登录后查看更多精彩内容~

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
主要是做显著性检验之后打点的程序。以下是主要程序部分

---------------------------------------------分割线---------------------------------------------------------

procedure add_markers(wks,plot,x,y)
local pmres, str
begin
  pmres = True
  pmres@gsMarkerIndex=1 ;cross
  pmres@gsMarkerThicknessF = 5.
  pmres@gsMarkerColor = "black"

  str = unique_string("polymarker")  ; "unique_string" will return a unique
                                     ; string every time it is called from
                                     ;  within a single NCL session.
;
; You can then use this unique string as an attribute variable name
; that gets attached to the plot variable. This ensures that this
; value will live for the duration of the script.
;
  plot@$str$ = gsn_add_polymarker(wks, plot, x, y, pmres)
end

这部分主要是定义一个打点的procedure

-----------------------------------------------------以下是主程序部分----------------------------------------------------------

begin
wks = gsn_open_wks("eps" ,"test")                ; open a ps file
gsn_define_colormap(wks,"posneg_2")        ; choose colormap
plot = new(1,graphic)

等等省略

plot(0) = gsn_csm_contour_map_ce(wks,x,res)
--------------------------------先画出不带显著性检验的原图(底图)------------------------------------------------

do i = 0,ny-1
    do j = 0,nx-1
        if (.not. ismissing(z_signif(i,j))) .and. (z_signif(i,j) .ge. 95)
             add_markers(wks,plot(0),lon(j),lat(i))
        end if
    end do
end do
------------------------遍历每个格点,凡是通过显著性检验的格点调用打点procedure----------------------------------

res_panel= True
res_panel@gsnPanelFigureStrings= (/"(a)"/) ; add strings to panel
res_panel@gsnPanelFigureStringsFontHeightF = .03
res_panel@amJust   = "TopLeft"
res_panel@gsnPanelLabelBar = True                   ; add common colorbar
  res_panel@lbLabelFontHeightF  = .018
  res_panel@lbTitleString    = "W m~S~-2~N~ 10yr~S~-1~N"
  res_panel@lbTitlePosition  = "Right"
  res_panel@lbTitleDirection = "Across"             ; title direction
  res_panel@lbTitleFontHeightF= .018                ; make title smaller
  res_panel@pmLabelBarWidthF      = 1.0

gsn_panel(wks,plot,(/1,1/),res_panel)
-------------------------------------------------------加上色标,标题等-----------------------------------------------------

end

这段程序如果打点量较小还可以,如果量大的话则可能要几个小时才能画完。
求各位高手提出优化意见
谢谢!!!!
密码修改失败请联系微信:mofangbao
发表于 2015-5-6 09:12:21 | 显示全部楼层
首先,不管什么语言 循环都是最耗时间的
其次,你自己能写函数说明ncl功底不错,难道没发现ncl除了填充颜色还能填充pattern?好好找找看看官网的例子吧
密码修改失败请联系微信:mofangbao
 楼主| 发表于 2015-5-6 11:24:13 | 显示全部楼层
井中月 发表于 2015-5-6 09:12
首先,不管什么语言 循环都是最耗时间的
其次,你自己能写函数说明ncl功底不错,难道没发现ncl除 ...

感谢您的回复。
首先那个procedure也不是我自己写的,也是参考例子的。整个程序最耗时的原因在于每打一次点,都要调用plot,也就是重新再画一次。您说的填充pattern,我现在查到的是gsn_contour_shade可以满足需求,但有一个问题是该函数是在原图的基础上设定数值范围然后填充,也就是说例如,我原图画的是斜率,但我需要根据拟合之后的相关系数来进行显著性检验,而不是根据斜率来设定数值范围。请问您是怎么处理的?
密码修改失败请联系微信:mofangbao
发表于 2015-5-6 13:01:00 | 显示全部楼层
如果是两个变量,可以画两次再overlay,原变量用color,显著性检验用pattern,用pattern填充等值线可参考contour effect例子中的第11个。ncl预定义了多种填充pattern,有点状的也有网格状的
很多显著性检验都不是原值,比如f检验 t检验,都是根据f值或者t值去判断原值的信度。比较常用的回归分析用的就是t检验
另外,即使是逐个格点打点似乎也不需要重新画一次plot,可以将plot作为底图加marker,比如http://ncl.ucar.edu/Applications/polyg.shtml第3个例子
密码修改失败请联系微信:mofangbao
发表于 2015-5-6 15:48:37 | 显示全部楼层
井中月 发表于 2015-5-6 13:01
如果是两个变量,可以画两次再overlay,原变量用color,显著性检验用pattern,用pattern填充等值线可参考co ...

请问 显著性检验用pattern 是不是用的gsn_contour_shade 这个是在显著性检验值的原图基础上填充的,所以

填充后除了填充色还有其他等值线之类的,如何只有某个值范围内的填充色,这样才好overlay到被检验变量图上
密码修改失败请联系微信:mofangbao
 楼主| 发表于 2015-5-6 22:35:55 | 显示全部楼层
井中月 发表于 2015-5-6 13:01
如果是两个变量,可以画两次再overlay,原变量用color,显著性检验用pattern,用pattern填充等值线可参考co ...

好的,非常感谢!我试试
密码修改失败请联系微信:mofangbao
发表于 2015-5-7 08:37:44 | 显示全部楼层
本帖最后由 井中月 于 2015-5-7 13:21 编辑
niuda 发表于 2015-5-6 15:48
请问 显著性检验用pattern 是不是用的gsn_contour_shade 这个是在显著性检验值的原图基础上填充的,所以
...

直接上我的程序吧  
  res = True
  res@gsnDraw = False    ;Don't draw graphics and frame,
  res@gsnFrame = False   ;in order to draw sevral subpots in on page
  res@gsnSpreadColors = True  ;use the whole color map
  res@gsnAddCyclic = False  ;the data does not cover the whole globe

;  res@gsnPolar             = "NH"        ; choose which hemisphere
;  res@gsnPolarLabelFontHeightF= .025

  res@mpFillOn = False
;  res@mpFillColor = "Foreground"
  res@mpMinLatF = latS
  res@mpMaxLatF = latN
  res@mpMinLonF = lonW
  res@mpMaxLonF = lonE
  res@mpCenterLonF = lonW+(lonE-lonW)/2.

  res@cnFillOn = True
  res@cnLinesOn = False   ;don't draw contour line
  res@cnLineLabelsOn = False   ;don't add contour value number
  res@cnLevelSelectionMode = "ExplicitLevels"
;  res@cnLevels = fspan(-3,3,13)/10. ;fspan(-0.5,0.5,11)   ;fspan(-1.2,1.2,13)             ;
  res@cnLevels = fspan(-0.5,0.5,11)
;
  res@tmXBLabelFontHeightF = 0.025         ; resize tick labels
  res@tmYLLabelFontHeightF = 0.025

  res@lbLabelBarOn = False ; turn off individual bar
;-----------------------
  cres = True
;  cres@gsnDraw          = False           ; don't draw
;  cres@gsnFrame         = False           ; don't advance frame
  cres@gsnAddCyclic = False  ;the data does not cover the whole globe
;  cres@tiMainString = ""            ; set the main title
  cres@cnInfoLabelOn = False

;  cres@gsnLeftString = ""
  cres@cnFillOn = True
  cres@cnLinesOn = False   ;don't draw contour line
  cres@cnLineLabelsOn = False   ;don't add contour value number

  cres@cnLevelSelectionMode = "ExplicitLevels"
  cres@cnLevels = 90.     ;!!!!!!!!!关键是这儿,可以改成你需要的值,如果t检验一类的,可能是1.234这样的数
  cres@cnMonoFillPattern = False
  cres@cnFillPatterns = (/-1,17/)     ;!!!!!!!!!配合上面设置填充的pattern,-1是不填,17是点状
  cres@cnFillColors = (/"black","black"/)

plot = gsn_csm_contour_map_overlay(wks,ssta,sstsig,res,cres)

@stepdance
密码修改失败请联系微信:mofangbao
发表于 2015-5-7 10:28:01 | 显示全部楼层
井中月 发表于 2015-5-7 08:37
直接上我的程序吧  
  res = True
  res@gsnDraw = False    ;Don't draw graphics and frame,

感谢分享,我尝试一下
密码修改失败请联系微信:mofangbao
 楼主| 发表于 2015-5-16 15:05:00 | 显示全部楼层
井中月 发表于 2015-5-7 08:37
直接上我的程序吧  
  res = True
  res@gsnDraw = False    ;Don't draw graphics and frame,

非常感谢,我再试试!
密码修改失败请联系微信:mofangbao
发表于 2015-5-21 12:27:55 | 显示全部楼层
井中月 发表于 2015-5-7 08:37
直接上我的程序吧  
  res = True
  res@gsnDraw = False    ;Don't draw graphics and frame,

请教如何使显著性的区域分别在相关系数是正的区域用一种颜色填充而负的区域用另一种颜色填充呢?
密码修改失败请联系微信:mofangbao
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Copyright ©2011-2014 bbs.06climate.com All Rights Reserved.  Powered by Discuz! (京ICP-10201084)

本站信息均由会员发表,不代表气象家园立场,禁止在本站发表与国家法律相抵触言论

快速回复 返回顶部 返回列表