|
4 L+ L8 A5 U% o$ u9 u( w 最近准备参加美赛,队伍拿了2020年美赛A题磨合。得到数据后我便在想着怎么把图做得好看点,不得不说matlab作为商业软件这方面确实好用,使用imagesc()函数便可以非常好地实现我的目的。 $ K8 w4 s8 [# j6 y
matlab程序代码:
7 N- d4 |6 }- Y# M: t %对图窗属性进行初始化# Q' B$ j1 m2 M, h6 l
figure1 = figure(1); %创建图窗并获取图窗句柄
S) i3 I" e2 w$ Y" z( l6 x2 X SIZE=get(0); %获取显示屏信息
1 y; p( I; s. |, w0 O set(figure1,outerposition,SIZE.ScreenSize); %设置图窗位置和外部尺寸为显示屏大小- L1 \: ^5 x6 y
C=zeros(180,360); %预分配内存
6 C4 O( x. L1 C% L SY=zeros(22,1); %用于存储每一份数据的起始年份
' W3 p( a, R1 |* t7 }& \ STR1=cell(22,1); %用于存储变量名
/ i3 X X7 V9 d% K8 L STR2=STR1; %%用于存储文件名" d( R2 w0 F- t3 _9 n9 P
clim=[-1000,3500]; %设定imagesc的数值范围! ~2 ]! z2 q7 Q- A) y% V
im=imagesc(C,clim); %创建image初始对象
# y+ g/ H& F" C& }% |: _# s0 B colormap(jet); %指定颜色映射类型为jet% I& T7 s5 J2 y
txt=text(320,175,0,," FontSize" ,20); %初始化一个text对象,用于显示年份和月份" f7 G; C3 z9 j. p) d- k0 z
title(Sea Surface Temperature (From 1870.1 to 2020.11),Interpreter,latex,FontSize,20);
" |* R7 S* L7 J3 f' |8 R axis off: z) L: e0 m; U0 `: h1 W ^$ w9 q# m
hold on3 _( s8 u1 S: O8 O5 U
cbar(); %显示预先设定的colorbar4 p+ I% f G+ a; Q$ O$ P& c
%%
6 c$ a( D% A2 ?1 v4 K! P+ Y filename = SST.mp4;
3 d, g% C% R& E2 ~ F8 } fps=10;5 y2 E. n9 [* f; s$ j7 @" M8 M0 ?
WriteObject=VideoWriter(filename,MPEG-4); %创建视频写入对象0 B! k0 E; i- k2 |2 P4 s6 e1 Y
WriteObject.FrameRate=fps;
9 E* E G1 W& T6 W5 v/ Z4 i WriteObject.Quality=100;& f# U* \! }: W4 ?7 T
open(WriteObject);
& |6 x& {" i- m. ~+ ]# i %%
) L+ x, b" m1 x/ [ SY(1:5,1)=[1870 1901 1931 1961 1991];0 h% ]( f/ i: o; u6 E/ g
STR1(1:5,1)={HadISST1SST18701900,HadISST1SST19011930,HadISST1SST19311960,HadISST1SST19611990,HadISST1SST19912003};
5 C" r5 l' y9 D* K3 }( b2 u STR2(1:5,1)={SST1870_1900,SST1901_1930,SST1931_1960,SST1961_1990,SST1991_2003};, ^7 {7 C" _3 M5 z( y; x
for m=4:19
; K5 Y& V. W* X* |. w# K sy=2000+m;% ]0 v$ ]+ D+ l
str1=[HadISST1SST20,num2str(m,%02d)];
) i. I# a' w$ {( ^6 B* o1 e str2=[SST20,num2str(m,%02d)];0 \/ @" ?& H. Y% n, T3 ~
SY(m+2,1)=sy;, b! z! W G5 W( U
STR1(m+2,1)={str1};
6 d$ C$ O; r( w7 u- b STR2(m+2,1)={str2};0 ^3 x! @2 `6 Q
end
0 k: K4 R, y3 e SY(end)=2020;
% h1 }: P5 i9 R/ f STR1(end)={HadISST1SST1};
' ?2 w; s1 e e2 A3 U6 L STR2(end)={SST2020};) X7 @# h' e9 f0 L
! c/ F/ _! S7 _7 c9 O [rowsize,~]=size(SY);4 ]0 W) L7 v2 K* E a5 d. c
for i=1:rowsize
% U3 K# G* p( V5 Z9 p shsst(STR1{i},STR2{i},C,SY(i),WriteObject,im,txt)9 N$ Q3 l+ g: F1 U
end# \. U! O4 D+ x
# o: p) k1 k3 A+ K8 {6 J, B5 m hold off5 S6 B4 m& H$ O7 O( w
close(WriteObject)
, o |9 M: P. i* j+ L' j$ R+ ]) l %%
9 Q. ?2 w& N, x" N functioncbar()Tem=(-10:5:35);
! M! C7 S/ A: m% ~; n% R5 m labcell=cell(1,10); %用于存储colorbar标签1 `$ G$ s% D% o( w
for i=1:10( T, R' f6 l! ~8 Y& Y, T# a# p0 C
labcell(i)={[${,int2str(Tem(i)),\,}^oC$]};. k1 V8 v1 R& @1 S3 o, I( O. R
end
& K1 m5 t4 e( `4 A3 Z% U& j cb=colorbar;
$ {6 u! M- H3 H2 } cb.TickLabelInterpreter=latex; %设置colorbar的刻度标签解释器为latex
% K7 w$ T" K# |, c. C+ k cb.TickLabels=labcell;
2 Q$ q/ w' Z0 m7 F; a cb.FontSize=12;
- f0 a$ O! |! U end! ?, i5 m( V* r- t
3 q% I. L- I; c; M% T' S% P, y
functionshsst(str1,str2,C,sy,WriteObject,im,txt )load([str2,.mat],str1);6 _" Q) x F2 R
eval([[n1,~]=size(,str1,);]); %利用eval()函数执行文本代表的语句
$ |7 s( B/ F2 e% g2 h. T n1=n1/181-1; %数据每181行是一个月的全球SST数据
% n2 y: @0 v0 Q7 v7 y7 \1 b2 ~ for i=0:n1
( _" |% e' T$ y8 Y1 o: I eval([C(:, =,str1,(2+181*i:181+181*i,1:360);]);
; D1 r m4 [9 K# f& I! Z: S& w C(C==-32768)=NaN;
/ F. L$ y9 {4 i1 f set(im,CData,C); %更新im的CData属性" c4 }5 t& f, n$ n
set(im,alphadata,1-isnan(C).*0.9); %利用isnan()函数标出NaN的位置并修改相应位置图形的透明度" v3 ]2 {, H8 C6 ~) m2 F+ }' Y3 S0 \
set(txt,String,[int2str(sy+floor(i/12)),-,int2str(mod(i,12)+1)]); %更新文本
9 N) S# J4 |" l* w( u5 w7 N; R' ?6 T) l
frame=getframe(gcf);
% t# @, E0 C. r& l( N* s, {5 V" `: N; A writeVideo(WriteObject,frame);/ _* Y; Z; q. s0 z$ q$ ^
end/ E2 x, U0 ] A E4 R
eval([clear ,str1]);8 [1 `/ I$ L: z8 s t2 G; q; S# z* H
end x7 Z& M. G: q- n- i! g0 }
% F9 B9 l. i5 Q, o 效果图:" y9 U; T' B" n. X" @
# |, S" \( e4 X0 N' C# a 数据来源网站: : b% g; A2 a% x
. D$ X- f2 |1 T! r- h
(引用声明: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/)
; \9 r' b- n4 W2 p; u 代码中使用的文件数据都是我已经处理好的,如果自己导入数据的话记得修改代码对应位置的文件名和变量名。这是我导出完成的mat文件:
" a5 o6 h# W O6 S0 g; N
, H/ D; j( Y( X3 V2 r& D; u. q 提取码8xt8。 2021.2.2更新有小伙伴私信问我那么一大堆数据具体是代表了个啥,在这里解释一下:原始数据是每181行储存了一个月的全球海洋表面温度数据,其中第一行是年月等信息,后面180行是180*360的矩阵,是将世界地图分成了180*360个小块,每一个数值大小代表了所在小块的温度,其中-32768代表陆地。(P.S.我看地图最北边越过陆地那块很多数值只是-1000或者-180,这是为啥我也不太清楚)
9 G, W" x+ r/ r+ x2 d" M/ h 参考文献: 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
; L4 ?- m; ~* U1 _! Q( u6 g
2 ~2 B5 }3 w- q- O5 T- h" v: h. U* K" H, y* [
# a) `# {/ G# s. h: V9 e
, K) P% ~* S6 G* I% u
|