|
2 Y9 K2 H+ W' F) s 最近准备参加美赛,队伍拿了2020年美赛A题磨合。得到数据后我便在想着怎么把图做得好看点,不得不说matlab作为商业软件这方面确实好用,使用imagesc()函数便可以非常好地实现我的目的。 2 p5 i) b; b' \7 G" O
matlab程序代码:+ A6 N8 u+ s7 A. u* Y* A
%对图窗属性进行初始化
8 H" ?/ e! q7 A7 g figure1 = figure(1); %创建图窗并获取图窗句柄
. n4 `" }7 k# e8 t$ C) B- [ SIZE=get(0); %获取显示屏信息# I( C; A. y0 q' V6 u
set(figure1,outerposition,SIZE.ScreenSize); %设置图窗位置和外部尺寸为显示屏大小2 T+ r8 B+ V. w9 l
C=zeros(180,360); %预分配内存
' c) w2 |7 t. V SY=zeros(22,1); %用于存储每一份数据的起始年份: x2 P6 t& X4 z! Q; V* Q
STR1=cell(22,1); %用于存储变量名
+ L0 W. g2 A; V* W6 h3 e: t7 G8 { STR2=STR1; %%用于存储文件名8 n0 q3 {( _- A( D( x6 R
clim=[-1000,3500]; %设定imagesc的数值范围
6 _3 [0 N5 }, ~+ O/ i$ A/ f( H im=imagesc(C,clim); %创建image初始对象7 h2 S5 c, D6 G* i2 ? q5 y$ |$ P
colormap(jet); %指定颜色映射类型为jet
. n t. A* K& h$ t txt=text(320,175,0,," FontSize" ,20); %初始化一个text对象,用于显示年份和月份
4 D6 g* \; S8 u% a# i title(Sea Surface Temperature (From 1870.1 to 2020.11),Interpreter,latex,FontSize,20);! s/ M/ l/ |0 R& T
axis off
4 P* S. R, y" p0 V$ K hold on. x, _, J, v, }9 t2 {$ h5 B
cbar(); %显示预先设定的colorbar
4 E/ |+ W3 L# O |- E) e+ i+ |5 j7 q! m %%( w- e/ [! H5 P1 m4 c1 d
filename = SST.mp4;) N3 C) z: u% w/ r9 |/ G; E
fps=10;
) a" N( H O+ Q& \ WriteObject=VideoWriter(filename,MPEG-4); %创建视频写入对象
+ j, x0 a& o5 w( m$ `& Z) o WriteObject.FrameRate=fps;6 E4 o6 b N5 Z+ a N& Y X5 f. V
WriteObject.Quality=100;7 `6 m- M3 L$ K i3 p' }
open(WriteObject);
$ W5 P- |3 b4 W7 X7 J %%) N/ b5 t- v; X( z/ P: M- y
SY(1:5,1)=[1870 1901 1931 1961 1991];& a, p( _1 @) b5 @
STR1(1:5,1)={HadISST1SST18701900,HadISST1SST19011930,HadISST1SST19311960,HadISST1SST19611990,HadISST1SST19912003};
* u- x: {+ j- C9 ^2 y3 B STR2(1:5,1)={SST1870_1900,SST1901_1930,SST1931_1960,SST1961_1990,SST1991_2003};
3 } h& F; l5 o3 x: f' E7 C4 \ for m=4:19
/ s4 Q" ~8 f I* r y sy=2000+m;
' ]0 X' B, l0 ~0 z+ K str1=[HadISST1SST20,num2str(m,%02d)];( x# ~( B+ v7 F% \/ \, x! i4 a$ ?
str2=[SST20,num2str(m,%02d)];
" M6 h* D$ k" n) }7 W+ i4 D. L, ] SY(m+2,1)=sy;& i% {- U" B+ G6 H
STR1(m+2,1)={str1};7 y5 B; W5 e R4 }
STR2(m+2,1)={str2};
$ _+ n) O* C1 @4 p1 R end! R+ C- z4 |2 m7 T; I. q% d
SY(end)=2020;
5 N( i2 D4 c5 Z! N STR1(end)={HadISST1SST1};
, p9 E+ v9 E7 C6 R& H' O( ]& x STR2(end)={SST2020};
& C( f% G" h6 i8 y. Q7 w! b. F6 R4 c3 g
[rowsize,~]=size(SY);" W4 a, S( P$ c. I$ r4 A$ j
for i=1:rowsize" `# {( x5 r) _
shsst(STR1{i},STR2{i},C,SY(i),WriteObject,im,txt)9 H6 H$ r; z& n d0 G/ ~
end1 v" K- i2 O& l Q" n& P: o
1 P8 C" ~& [/ s" t3 |0 ~, {6 V hold off
& M4 E3 e- X! r" W6 a( u2 i( I& U close(WriteObject)
/ y# T5 K( ^6 T1 w# Z4 n %%
1 G* i. q+ w5 U functioncbar()Tem=(-10:5:35);
% n: U. p" M5 a4 M labcell=cell(1,10); %用于存储colorbar标签
- [' o0 ~* F6 H$ N for i=1:10+ N; n S1 G' r: z# J
labcell(i)={[${,int2str(Tem(i)),\,}^oC$]};: P! C$ c. I2 z# B8 J; [2 Y- A6 d4 L
end! l; Y+ s3 g5 |# A6 o
cb=colorbar;
$ K6 ?" {: O) C cb.TickLabelInterpreter=latex; %设置colorbar的刻度标签解释器为latex* w( t1 R' A9 a% ~8 @3 }
cb.TickLabels=labcell;
7 D1 c8 U0 a+ g# Z6 o cb.FontSize=12;
' H% d6 s* H; v& h, A2 Y end
: S& c1 P" I! V8 L8 Z2 Y5 n1 C' Y. E+ N
/ Z/ ?' Y4 t' S4 y4 C% P1 G functionshsst(str1,str2,C,sy,WriteObject,im,txt )load([str2,.mat],str1);2 e% D' K. i+ A) D3 C
eval([[n1,~]=size(,str1,);]); %利用eval()函数执行文本代表的语句3 ]7 B: Z |: X8 C2 l' S
n1=n1/181-1; %数据每181行是一个月的全球SST数据# q+ w G: E; o( U* E" s3 g
for i=0:n1) d7 T, Y* b9 y+ d
eval([C(:, =,str1,(2+181*i:181+181*i,1:360);]);
3 |% j5 p0 M% W' {+ C; [5 W C(C==-32768)=NaN;+ T. `* A8 q/ u6 B, K# ?
set(im,CData,C); %更新im的CData属性
% S# \" Y9 v& G8 P( k$ O set(im,alphadata,1-isnan(C).*0.9); %利用isnan()函数标出NaN的位置并修改相应位置图形的透明度
3 D5 Y2 f" I$ i2 a& V set(txt,String,[int2str(sy+floor(i/12)),-,int2str(mod(i,12)+1)]); %更新文本
) ~( s8 m; b/ U0 F; y4 M- b' ]8 r% `0 f
frame=getframe(gcf);8 {8 [: D# e) v7 z9 e0 f8 [
writeVideo(WriteObject,frame); ?7 f& Y1 x) C+ e5 N
end. r1 @) L+ w7 J; m& t$ b1 k4 b/ U
eval([clear ,str1]);
! ~4 d0 s! ?1 c: Y end
( \% G- ^( I/ X6 {: U 7 Y; g& X' }4 e$ g
效果图:: b# a3 N4 p. J: V5 x7 W! j
7 ]2 r& G+ Y# o% E3 I 数据来源网站:
! G/ @% { H# e- w
: X- D, N; z4 _) P) D (引用声明:HadISST data were obtained from https://www.metoffice.gov.uk/hadobs/hadisst/ and are © British Crown Copyright, Met Office, [year of first publication], provided under a Non-Commercial Government Licence http://www.nationalarchives.gov.uk/doc/non-commercial-government-licence/version/2/)
: w$ a6 j3 D) W" u; l4 c 代码中使用的文件数据都是我已经处理好的,如果自己导入数据的话记得修改代码对应位置的文件名和变量名。这是我导出完成的mat文件:
) R4 S3 e" G$ j1 I 6 u$ \% Y) Q1 {. ~! u$ A5 |
提取码8xt8。 2021.2.2更新有小伙伴私信问我那么一大堆数据具体是代表了个啥,在这里解释一下:原始数据是每181行储存了一个月的全球海洋表面温度数据,其中第一行是年月等信息,后面180行是180*360的矩阵,是将世界地图分成了180*360个小块,每一个数值大小代表了所在小块的温度,其中-32768代表陆地。(P.S.我看地图最北边越过陆地那块很多数值只是-1000或者-180,这是为啥我也不太清楚)
$ \1 z! o# n! P# F 参考文献: Rayner, N. A.; Parker, D. E.; Horton, E. B.; Folland, C. K.; Alexander, L. V.; Rowell, D. P.; Kent, E. C.; Kaplan, A. (2003) Global analyses of sea surface temperature, sea ice, and night marine air temperature since the late nineteenth century J. Geophys. Res.Vol. 108, No. D14, 4407 10.1029/2002JD002670! b, y% y7 g! N2 v
% Z* h3 o9 L k k( g
4 p& S) L/ g% \0 p$ V$ o( j( D
z/ C/ K* Y0 h0 ~, F
+ P* L' J+ _) n# l2 \9 z7 ^% \0 H |