. k) P2 J) n) e. m5 O 最近准备参加美赛,队伍拿了2020年美赛A题磨合。得到数据后我便在想着怎么把图做得好看点,不得不说matlab作为商业软件这方面确实好用,使用imagesc()函数便可以非常好地实现我的目的。
' E+ z& W8 n: Z) j8 n7 t; ^. u5 o matlab程序代码:0 N: L+ e5 \3 W2 ?
%对图窗属性进行初始化 U! L' i. _0 ?; q
figure1 = figure(1); %创建图窗并获取图窗句柄9 x$ w; b ^1 O
SIZE=get(0); %获取显示屏信息
' B) h3 A0 P: X, M& p set(figure1,outerposition,SIZE.ScreenSize); %设置图窗位置和外部尺寸为显示屏大小
3 a' `4 t4 U5 |$ o! M; E _ C=zeros(180,360); %预分配内存
& h+ q, K9 S9 I9 B2 m3 u8 n4 G/ A SY=zeros(22,1); %用于存储每一份数据的起始年份
_' ], ~( L- [+ S R/ X# Q" s' p STR1=cell(22,1); %用于存储变量名
8 H0 R/ T: y% Y STR2=STR1; %%用于存储文件名
6 }6 a# N5 _% r clim=[-1000,3500]; %设定imagesc的数值范围
Y' ^ F) r5 V3 q5 c im=imagesc(C,clim); %创建image初始对象
0 |2 O. O/ R5 W8 y colormap(jet); %指定颜色映射类型为jet1 o0 O3 n- N; R2 E8 S* Q6 _
txt=text(320,175,0,," FontSize" ,20); %初始化一个text对象,用于显示年份和月份4 R; a. K$ L4 ~' R
title(Sea Surface Temperature (From 1870.1 to 2020.11),Interpreter,latex,FontSize,20);- A7 c+ K# e4 g# A$ o0 }/ H' f
axis off
. Z8 p* P d5 p: J: ~9 g" Y hold on
) `/ w1 c- ?) ]! |, Z# Y, N$ w cbar(); %显示预先设定的colorbar
, B4 E9 x' k( }4 L6 s6 u9 T9 E: J %%
5 w3 O3 n$ Y- s" W$ q$ Q5 y filename = SST.mp4;
/ l4 w, f* v4 y fps=10;7 B0 C' E3 h- `) ]% l7 c1 q
WriteObject=VideoWriter(filename,MPEG-4); %创建视频写入对象' h5 ^- j9 W f! r/ H9 m" Y
WriteObject.FrameRate=fps;
% t3 V e+ n2 z& m WriteObject.Quality=100;% t" Q8 K- |" ^* }+ Z
open(WriteObject);9 g9 @' Z- G4 r3 A
%%% A! w; t, m+ r
SY(1:5,1)=[1870 1901 1931 1961 1991];4 S. l3 D+ E" ?& r g; B8 X
STR1(1:5,1)={HadISST1SST18701900,HadISST1SST19011930,HadISST1SST19311960,HadISST1SST19611990,HadISST1SST19912003};, V; m' b2 L8 C: Q _' V8 V) H& l
STR2(1:5,1)={SST1870_1900,SST1901_1930,SST1931_1960,SST1961_1990,SST1991_2003};
; ]( N2 l2 M9 G) s; X2 V) r for m=4:19$ M5 M% ~* z; `* Y
sy=2000+m;) i, C2 @% R$ E$ I
str1=[HadISST1SST20,num2str(m,%02d)];
2 g5 y( b+ b" f# R: b, c str2=[SST20,num2str(m,%02d)];
8 U1 A+ t, q* z SY(m+2,1)=sy;
+ y$ ^/ R2 w3 Z' ?/ Y STR1(m+2,1)={str1};
! ]7 D7 h* {) |2 Y) j3 i9 d. x! v STR2(m+2,1)={str2};
" J$ i9 [& m* T" I/ a6 P* m end
/ O, X0 b- v3 d; i3 b SY(end)=2020;* n9 A+ o, x( W" L7 H' q
STR1(end)={HadISST1SST1};
# T$ u; `$ O- P' b* C STR2(end)={SST2020};+ P, @' `; P/ i
1 ?# D- N! r/ R [rowsize,~]=size(SY);. T& B3 C' _. E( u" c9 k
for i=1:rowsize8 Y F0 |0 ?) w4 l( l. Q
shsst(STR1{i},STR2{i},C,SY(i),WriteObject,im,txt)
0 |1 z+ `( j$ `4 H end* C2 C7 k8 l/ F
" j9 a3 m0 h& M hold off0 o: m2 e* s' D7 A* c
close(WriteObject)7 v: z+ p% q2 M) \3 M
%%
9 O; ~: H" A5 I3 [3 o functioncbar()Tem=(-10:5:35);
) y, r: f3 ^9 c labcell=cell(1,10); %用于存储colorbar标签
. O6 I/ x; \$ z: A- m( a9 _. ~ for i=1:10( | M* g; Q% O) R
labcell(i)={[${,int2str(Tem(i)),\,}^oC$]};$ [. q( N0 r! J. r
end2 S# ^+ d3 m3 B; v. P
cb=colorbar;
! F& P- q( X4 x {+ Y7 a cb.TickLabelInterpreter=latex; %设置colorbar的刻度标签解释器为latex( Q5 r: w& X3 Y# S' P
cb.TickLabels=labcell;
; B2 z% }9 ~- H* d cb.FontSize=12;
7 q4 e1 _5 s1 Z; H S7 o1 d+ {0 T) a end
7 A1 ?# E6 P k
& j: p) n9 ]$ N N; U. \; \8 l9 F" m functionshsst(str1,str2,C,sy,WriteObject,im,txt )load([str2,.mat],str1);
( X3 r9 T8 x/ Z9 X9 R% D! ]" y* i eval([[n1,~]=size(,str1,);]); %利用eval()函数执行文本代表的语句
# y) W/ ^/ G# i5 t5 | n1=n1/181-1; %数据每181行是一个月的全球SST数据0 E7 J* P& }/ C, H6 C$ ]. y v- l
for i=0:n1
5 G8 F1 g& R: x8 o) B eval([C(:, =,str1,(2+181*i:181+181*i,1:360);]);
) `6 x, y' y5 |. K' A0 A/ \3 r4 @" y' k C(C==-32768)=NaN;
/ e9 s' z/ |, D/ ^" O8 O$ v set(im,CData,C); %更新im的CData属性
; N1 z3 W# ~6 G; h6 t% M& U, U set(im,alphadata,1-isnan(C).*0.9); %利用isnan()函数标出NaN的位置并修改相应位置图形的透明度 L5 ^, u0 |* ], b1 {
set(txt,String,[int2str(sy+floor(i/12)),-,int2str(mod(i,12)+1)]); %更新文本5 \/ c$ [ p3 [ i8 }. N2 M+ V0 c
. N) v! r \+ D( {. H- j- c frame=getframe(gcf);
( a! r# s" x, r* y9 L. w- }% m/ S writeVideo(WriteObject,frame);. K; o7 H2 \1 e$ W8 D
end
3 S2 U. p' [9 p+ U4 D" K5 [ eval([clear ,str1]);( j% w5 ?! w# x- z
end* R0 b! u4 Z/ H# A
( Y' K( \" v0 k/ `* P; A' D 效果图:
# e" H" _ ?2 G% W5 ]9 @
3 K8 e) F5 q$ @3 H7 g' G 数据来源网站:
' [) c$ h5 J, ^/ u: d : @4 W- V. M5 r' f
(引用声明: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/)
6 S5 r3 Q6 L, f5 J1 w! a 代码中使用的文件数据都是我已经处理好的,如果自己导入数据的话记得修改代码对应位置的文件名和变量名。这是我导出完成的mat文件: : D' \& d( a; ]8 Y: \+ P% G
1 W3 ]9 { w% x) s6 ^; y/ {% C! F 提取码8xt8。 2021.2.2更新有小伙伴私信问我那么一大堆数据具体是代表了个啥,在这里解释一下:原始数据是每181行储存了一个月的全球海洋表面温度数据,其中第一行是年月等信息,后面180行是180*360的矩阵,是将世界地图分成了180*360个小块,每一个数值大小代表了所在小块的温度,其中-32768代表陆地。(P.S.我看地图最北边越过陆地那块很多数值只是-1000或者-180,这是为啥我也不太清楚) / o1 g& W! W7 s
参考文献: 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
. l! u0 E' Z" h/ J
# M- S1 I! \) ]) ~, w. c! F3 m7 R# O1 q5 W; H
9 `! j R. c l) m3 g! v
5 Z% @/ L4 A# _, y# |) O |