) ^( k3 X, C5 t/ I& p$ [
最近准备参加美赛,队伍拿了2020年美赛A题磨合。得到数据后我便在想着怎么把图做得好看点,不得不说matlab作为商业软件这方面确实好用,使用imagesc()函数便可以非常好地实现我的目的。
9 h/ p( F/ C# [: x9 J" u4 d matlab程序代码:
6 I, `# M5 \3 W! Y# c7 l7 } %对图窗属性进行初始化; K4 T- c/ D8 O2 N6 k; t- A% `
figure1 = figure(1); %创建图窗并获取图窗句柄
7 V5 v& U; k9 q. K2 E SIZE=get(0); %获取显示屏信息- q8 n& d$ f; b4 u/ e @% v d
set(figure1,outerposition,SIZE.ScreenSize); %设置图窗位置和外部尺寸为显示屏大小4 ?; j b( j% Y8 A2 z6 |
C=zeros(180,360); %预分配内存- {9 l3 I( g6 G9 M9 O& M
SY=zeros(22,1); %用于存储每一份数据的起始年份% ?: D; e! V, O
STR1=cell(22,1); %用于存储变量名
# |% ]5 `% c5 Q STR2=STR1; %%用于存储文件名
6 ~1 l' C% T A clim=[-1000,3500]; %设定imagesc的数值范围
" A% B3 z6 W8 U: l3 i) [ im=imagesc(C,clim); %创建image初始对象
5 X' Q/ [6 J" e; N0 { colormap(jet); %指定颜色映射类型为jet
! I# g. ^& `7 P. P txt=text(320,175,0,," FontSize" ,20); %初始化一个text对象,用于显示年份和月份
! u+ r4 b. j( z' \ title(Sea Surface Temperature (From 1870.1 to 2020.11),Interpreter,latex,FontSize,20);/ d- N0 W6 w6 e5 _& L
axis off
# j/ P, q- e* R& ^3 {& j% Q hold on, \3 j5 j+ [ X
cbar(); %显示预先设定的colorbar8 ]$ v' v, Q4 W8 u' ?* L8 m# z Y
%%9 ]5 V( l9 q' T% d, I$ ~' B& ~
filename = SST.mp4;( u9 V" e4 l# x" P7 F2 Y
fps=10;% A% f# N# ]: ?$ c. n8 r
WriteObject=VideoWriter(filename,MPEG-4); %创建视频写入对象
0 x2 f7 E( l* p; q- ] WriteObject.FrameRate=fps;& P! G R0 n7 s- [
WriteObject.Quality=100;8 h/ k+ ]% o+ o: A4 m. K9 j
open(WriteObject);3 T& \8 U9 v" G
%%
6 o, q. B7 m f9 E7 q2 b4 c. ] SY(1:5,1)=[1870 1901 1931 1961 1991];% o$ l K% v1 `! x$ C3 H3 M7 |
STR1(1:5,1)={HadISST1SST18701900,HadISST1SST19011930,HadISST1SST19311960,HadISST1SST19611990,HadISST1SST19912003};
% ~: M8 i' [! W! w0 m STR2(1:5,1)={SST1870_1900,SST1901_1930,SST1931_1960,SST1961_1990,SST1991_2003};
. n E. D/ }& ?5 _- u for m=4:19
& S `! z W q7 U0 D sy=2000+m;
! h# }( O3 F; j# r1 c1 s( t% f. a str1=[HadISST1SST20,num2str(m,%02d)];& D) J1 n2 n8 c( j
str2=[SST20,num2str(m,%02d)];
# p* |% O, m' d4 R SY(m+2,1)=sy;
% [# d8 A, ], A0 c3 b6 q, T F STR1(m+2,1)={str1};" G' h, B" z. i# @4 t
STR2(m+2,1)={str2};1 _" E! L9 H4 f! R/ B0 S
end2 b& b! c, H% P( B% ~: e( j
SY(end)=2020;8 ]5 y# Z7 D; A8 @; p
STR1(end)={HadISST1SST1};+ g: n9 |+ g$ i( m
STR2(end)={SST2020};
3 ^: g/ Q8 Y' Z9 C( S) U, } y5 ?0 f% B3 m
[rowsize,~]=size(SY);' A! s3 o+ ?4 V- X& h8 i
for i=1:rowsize
1 ]3 F) O$ N# d& t' s$ G: b6 r, y shsst(STR1{i},STR2{i},C,SY(i),WriteObject,im,txt)* n' b2 [. f- _$ U+ X1 d
end6 b+ S+ @ U' L/ h6 n9 |" v9 L6 ^, v
* I4 Y0 K8 J7 h3 k& x# } hold off
- ?- L" T. k: E. q2 [ close(WriteObject)
* q) K w9 }+ }: x3 R %%. w: C- y1 k* V9 \# i
functioncbar()Tem=(-10:5:35);1 r8 r; o# w7 w+ U6 P: V2 m
labcell=cell(1,10); %用于存储colorbar标签: R3 j, Y5 R& A; y$ H
for i=1:10
! r; E: A- p; @& C$ { labcell(i)={[${,int2str(Tem(i)),\,}^oC$]};7 m7 Q# R1 Q! D2 W4 \8 U9 r- I% e
end
# r: K$ [% {7 n2 F" D' u) P cb=colorbar;
U) `# c) K5 t' _5 s o3 E0 @ cb.TickLabelInterpreter=latex; %设置colorbar的刻度标签解释器为latex8 E$ o- c! G' D3 ~9 `
cb.TickLabels=labcell;7 J, Z$ m, p9 n f3 c5 ~4 w& e6 B
cb.FontSize=12;
/ g7 N% g6 d7 u4 z8 D3 ~ end
9 U- D5 h4 J% ]1 M* u/ F
# \7 M9 m4 H& D2 A functionshsst(str1,str2,C,sy,WriteObject,im,txt )load([str2,.mat],str1);1 K' Q" {" N; q: q! b' f
eval([[n1,~]=size(,str1,);]); %利用eval()函数执行文本代表的语句# h8 k5 u( W0 L- R8 m* G# s
n1=n1/181-1; %数据每181行是一个月的全球SST数据
+ R7 u5 n% m) @0 K, h* ]7 p for i=0:n1
1 R0 K3 u/ W/ R. s! H( R eval([C(:,=,str1,(2+181*i:181+181*i,1:360);]);
& e. \5 `5 k" T) J8 j9 H C(C==-32768)=NaN;. ^/ V4 W/ J O r$ s4 P
set(im,CData,C); %更新im的CData属性
9 g+ k W8 n3 m' E5 R1 K set(im,alphadata,1-isnan(C).*0.9); %利用isnan()函数标出NaN的位置并修改相应位置图形的透明度8 N5 w4 u' N) `
set(txt,String,[int2str(sy+floor(i/12)),-,int2str(mod(i,12)+1)]); %更新文本
: ^' e5 ]" K0 k" [
' c3 f, |: G5 r) U1 M% Z frame=getframe(gcf);- n! j* q- C% ~8 h; w
writeVideo(WriteObject,frame);9 X2 t' A3 L! C: d
end
$ B) W/ l0 C" O: j eval([clear ,str1]);% A m8 N5 d! b* V, S% {1 S4 |: O: _
end. s! m) l" A9 G( w7 [1 h9 J
$ ]$ n- P' z4 {' ]% ~, w+ ^7 t 效果图:
0 m6 z% U! ]2 {4 Y2 ]1 s 0 Z) ]/ p5 l7 L9 Q" H' t" @) w
数据来源网站:
. f: C/ f5 R0 V3 X$ |& X ; ]) ~5 _) y6 `2 \3 m0 I5 [1 S& T
(引用声明: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/)
% v1 F6 Y. ^( E1 N 代码中使用的文件数据都是我已经处理好的,如果自己导入数据的话记得修改代码对应位置的文件名和变量名。这是我导出完成的mat文件: 7 N" {. r+ {: D1 z1 i: e) q
2 O- f! w$ T- s1 _3 f( w$ i: O
提取码8xt8。 2021.2.2更新有小伙伴私信问我那么一大堆数据具体是代表了个啥,在这里解释一下:原始数据是每181行储存了一个月的全球海洋表面温度数据,其中第一行是年月等信息,后面180行是180*360的矩阵,是将世界地图分成了180*360个小块,每一个数值大小代表了所在小块的温度,其中-32768代表陆地。(P.S.我看地图最北边越过陆地那块很多数值只是-1000或者-180,这是为啥我也不太清楚) # U! O( P' x6 Z1 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* m' p. ?' L6 l" J! x* W f, m
8 H* v; H! z V/ M6 c
" [- H& q, g( R% |0 f
( J8 h# j* e e8 P- l; ]
, O! a$ \2 r: I! M |