! p; T* E( g+ i4 E% X7 J
最近准备参加美赛,队伍拿了2020年美赛A题磨合。得到数据后我便在想着怎么把图做得好看点,不得不说matlab作为商业软件这方面确实好用,使用imagesc()函数便可以非常好地实现我的目的。 5 t: y& ?6 D% {; r& `. i
matlab程序代码:, ` _$ F! J9 Z0 y
%对图窗属性进行初始化
?9 y8 l c) M( \' M# a0 ^& d figure1 = figure(1); %创建图窗并获取图窗句柄5 M2 i; P- p5 \6 ~5 \5 L. V: G
SIZE=get(0); %获取显示屏信息
X) J9 P6 i2 U set(figure1,outerposition,SIZE.ScreenSize); %设置图窗位置和外部尺寸为显示屏大小8 ]* J' j0 A+ t& E @
C=zeros(180,360); %预分配内存
0 B( D6 n$ P5 o4 p) \ SY=zeros(22,1); %用于存储每一份数据的起始年份
0 Z: x* d9 P# y/ k' O STR1=cell(22,1); %用于存储变量名
8 R/ L# _/ \0 _6 | STR2=STR1; %%用于存储文件名
& {2 y+ F. J# b- ^ clim=[-1000,3500]; %设定imagesc的数值范围
9 F0 I; W( u9 l) S im=imagesc(C,clim); %创建image初始对象
9 G2 a- i9 Y0 `1 J/ i; F1 J colormap(jet); %指定颜色映射类型为jet
5 K/ t+ @6 n- g. S# |# _( U, _ txt=text(320,175,0,," FontSize" ,20); %初始化一个text对象,用于显示年份和月份2 T- {$ }' x; `; D
title(Sea Surface Temperature (From 1870.1 to 2020.11),Interpreter,latex,FontSize,20);& ?. R& K, ?* x8 b9 [
axis off
6 P1 v7 a* `* } hold on
2 f; a+ M/ ], }) e2 |4 U e$ E cbar(); %显示预先设定的colorbar5 a9 x/ p; Y a% i
%%* [( H9 ]$ |" W' @5 H
filename = SST.mp4;# p3 `8 `' b, v" |7 C
fps=10;4 B4 F1 L8 W8 V# }$ Q1 B( l
WriteObject=VideoWriter(filename,MPEG-4); %创建视频写入对象
0 O: r1 J {, S; t9 p B( r/ h WriteObject.FrameRate=fps;
! f- S8 E c( ~4 W+ N- W WriteObject.Quality=100;. h$ k! w; ?& q3 D/ @, u1 Y2 \- p) o
open(WriteObject);
# F! @' x# Q1 n' N, B( m, j6 H %%
8 y% l, }6 @; @+ B# h SY(1:5,1)=[1870 1901 1931 1961 1991];
% q( Z r: q x; y3 C STR1(1:5,1)={HadISST1SST18701900,HadISST1SST19011930,HadISST1SST19311960,HadISST1SST19611990,HadISST1SST19912003};. A9 I1 u# u0 _. P; S+ a
STR2(1:5,1)={SST1870_1900,SST1901_1930,SST1931_1960,SST1961_1990,SST1991_2003};
+ G, X# @& R# W" j+ R& p6 I" p for m=4:19+ p+ h% h2 t( B/ o6 n/ o
sy=2000+m;
3 q* z+ v) [* u: v str1=[HadISST1SST20,num2str(m,%02d)];( s5 G4 s7 h( p9 v9 K
str2=[SST20,num2str(m,%02d)];) S2 D1 s8 O" Z3 B# q% V8 f
SY(m+2,1)=sy;! [" W! _& U# [* v* ~
STR1(m+2,1)={str1};" M' b' Z( Z4 W$ B5 m2 @
STR2(m+2,1)={str2};
! u- z1 Y; l' o7 l3 U( C; e end6 v- O, y6 T2 Y3 D" L
SY(end)=2020;
% z& n. v" |+ l$ j* Z STR1(end)={HadISST1SST1};6 U3 {" S, b3 ?% Y5 l
STR2(end)={SST2020};
" }0 X3 m8 n. x+ S `- t
" I1 R# h7 d1 t% l( r* Z [rowsize,~]=size(SY);1 k& H3 v0 U3 N+ y2 Y
for i=1:rowsize
1 x/ E, g2 }/ x# t2 ~ shsst(STR1{i},STR2{i},C,SY(i),WriteObject,im,txt)* d/ t- I& V6 e8 [; V" V# C" z r( g& C
end/ n5 E0 s- N6 i+ l& }3 e2 x. F
. E2 V) @7 H4 Y2 z hold off
0 I8 A& H1 a, E$ h0 c2 d* @ close(WriteObject)4 @, c- ~+ G6 a
%%) z0 P/ u5 a5 |( Z" p: h
functioncbar()Tem=(-10:5:35);0 X4 w6 {9 B5 {7 G! d& M) N5 b
labcell=cell(1,10); %用于存储colorbar标签7 b V+ ~" i8 d+ W/ U* \) l
for i=1:10; U6 K3 y# z+ R6 r( m N% G
labcell(i)={[${,int2str(Tem(i)),\,}^oC$]};
' [5 P9 `* o4 i end$ {- j" r- K( J% b9 X' R. l
cb=colorbar;8 }2 Z' r! Y% U t
cb.TickLabelInterpreter=latex; %设置colorbar的刻度标签解释器为latex
) G+ ? k5 ?- N& b. O cb.TickLabels=labcell;4 g* j5 O$ d3 L
cb.FontSize=12;
7 q0 N) ^7 N0 W4 Y6 y end
$ {& U& |) |" O7 v8 j K& I: H/ d! \
5 Z0 }2 }2 e( {3 P5 g functionshsst(str1,str2,C,sy,WriteObject,im,txt )load([str2,.mat],str1);9 i* ^' v) I& W: x# A
eval([[n1,~]=size(,str1,);]); %利用eval()函数执行文本代表的语句
8 h& \( N# @8 C; h n1=n1/181-1; %数据每181行是一个月的全球SST数据% Q0 D. _2 D' B' d
for i=0:n1
9 v5 @% r, H3 S) ^( P- X" l' L eval([C(:,=,str1,(2+181*i:181+181*i,1:360);]);; |' v$ V9 G6 }1 v+ e
C(C==-32768)=NaN;1 s, p- h0 t; e$ g
set(im,CData,C); %更新im的CData属性
- ?# L8 ], q1 ~- ]0 ? ~" B+ C set(im,alphadata,1-isnan(C).*0.9); %利用isnan()函数标出NaN的位置并修改相应位置图形的透明度 s% T+ c7 ? B& \6 T! y
set(txt,String,[int2str(sy+floor(i/12)),-,int2str(mod(i,12)+1)]); %更新文本
0 V1 b6 p/ f: s$ ~$ S8 a- |3 W5 @- h2 I$ i* M
frame=getframe(gcf);
8 Z9 C, e6 W Q+ F q writeVideo(WriteObject,frame);
2 w5 k0 `5 u, q! E7 d8 S end
: u7 r% ]% V& E, S eval([clear ,str1]);
% o: U5 G9 T% a2 U4 K/ h+ J, j end
& j* C' S' M9 K
7 b# E1 t/ x% I4 r 效果图:+ H+ |2 [' s# c/ w! D
/ N8 G/ q& r2 p. q. b! \8 E
数据来源网站: 7 p/ l7 H9 L+ T9 F& L; T
( P. _4 s; }6 I, n (引用声明: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/)
( f: A4 p! o/ H$ I' Y' k 代码中使用的文件数据都是我已经处理好的,如果自己导入数据的话记得修改代码对应位置的文件名和变量名。这是我导出完成的mat文件: " e7 m8 [" P8 j0 Q. ]) S: Z
# E, p( O/ o- l4 ~2 l8 u
提取码8xt8。 2021.2.2更新有小伙伴私信问我那么一大堆数据具体是代表了个啥,在这里解释一下:原始数据是每181行储存了一个月的全球海洋表面温度数据,其中第一行是年月等信息,后面180行是180*360的矩阵,是将世界地图分成了180*360个小块,每一个数值大小代表了所在小块的温度,其中-32768代表陆地。(P.S.我看地图最北边越过陆地那块很多数值只是-1000或者-180,这是为啥我也不太清楚) ' }- l% A9 d9 `1 S' t$ W3 w
参考文献: 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
9 q$ U" r( \9 I) t/ I5 ^4 N. g
! m# r7 @2 y5 j. t6 H; W% ?$ n+ A$ I& {' X# z+ `& I1 G
) {# N. z$ P' E$ t9 f
& _0 s& Z b8 Z( z! X3 W |