# ^: k0 K0 r' h- V. z9 E7 Q 最近准备参加美赛,队伍拿了2020年美赛A题磨合。得到数据后我便在想着怎么把图做得好看点,不得不说matlab作为商业软件这方面确实好用,使用imagesc()函数便可以非常好地实现我的目的。
+ J+ c5 J, s) t0 x matlab程序代码:" p+ d# L1 l. t, W
%对图窗属性进行初始化
/ b2 l) T* a6 ? figure1 = figure(1); %创建图窗并获取图窗句柄7 ^1 A5 V: A5 O& \- e
SIZE=get(0); %获取显示屏信息
+ Y m& |9 o! `' N set(figure1,outerposition,SIZE.ScreenSize); %设置图窗位置和外部尺寸为显示屏大小 S0 }6 c! G/ `7 ^& Z. B: i' P
C=zeros(180,360); %预分配内存* Q# k) _' z( g: x: M- z
SY=zeros(22,1); %用于存储每一份数据的起始年份
7 h0 }! I) U$ q |% C STR1=cell(22,1); %用于存储变量名
0 I1 V8 w& O, Q. x8 @7 D STR2=STR1; %%用于存储文件名
- H# p) ]. W" h6 _ clim=[-1000,3500]; %设定imagesc的数值范围* {% h* ]; ?2 P5 O# _
im=imagesc(C,clim); %创建image初始对象
1 [1 |( z% k; F2 @* h% l' A colormap(jet); %指定颜色映射类型为jet; y# {; V( \0 z' f6 [
txt=text(320,175,0,," FontSize" ,20); %初始化一个text对象,用于显示年份和月份& D$ s" w0 H' T. _
title(Sea Surface Temperature (From 1870.1 to 2020.11),Interpreter,latex,FontSize,20);. Z" c- Y2 m3 @( V, F$ f$ v7 @8 K
axis off) Q# t3 C7 e1 N" v! E
hold on
& q$ ^3 Y! ]6 x% n cbar(); %显示预先设定的colorbar" p" `' w, ~9 f1 f$ c( S' q) J$ L
%%
! ~8 e& j* a6 h5 A# J filename = SST.mp4;
g+ E7 n- ^6 N1 l fps=10;
X! P- V/ ^+ \1 c% W WriteObject=VideoWriter(filename,MPEG-4); %创建视频写入对象% u8 D( I5 s3 d) |' L
WriteObject.FrameRate=fps;9 y$ L# Q2 Q3 [1 [) K
WriteObject.Quality=100;
4 ]2 ~' t3 J9 ^3 o0 C/ J open(WriteObject);% g+ x& @6 {7 [& f: o5 O3 e7 x' @; ?
%%0 [% s: S7 n, ?+ l% U/ _! g/ ]
SY(1:5,1)=[1870 1901 1931 1961 1991];
; C, h" C& L; T STR1(1:5,1)={HadISST1SST18701900,HadISST1SST19011930,HadISST1SST19311960,HadISST1SST19611990,HadISST1SST19912003};
# {0 A; r3 N& G! V$ j; D STR2(1:5,1)={SST1870_1900,SST1901_1930,SST1931_1960,SST1961_1990,SST1991_2003};
5 s n- [* G" O/ f. q0 A for m=4:19
4 q4 u. n+ b# T! Z$ p; m# g( z sy=2000+m;" j/ d* U9 ]* J" \. B3 U
str1=[HadISST1SST20,num2str(m,%02d)];7 D2 H: D, ]7 o5 E' M8 ]
str2=[SST20,num2str(m,%02d)];( f" _* J% L, o( L6 e% P
SY(m+2,1)=sy;% o0 m+ Z/ O6 C4 u" o% |2 e
STR1(m+2,1)={str1};
1 x2 g' k, x/ w STR2(m+2,1)={str2};4 H+ y# q& W! B0 x2 e0 A
end; L7 |: j8 k# z
SY(end)=2020;4 i }. g e- B) p- Q6 }
STR1(end)={HadISST1SST1};/ X* k+ Z+ D \- S
STR2(end)={SST2020};
6 H+ |+ W# u* @6 _. _9 \9 s9 d8 R! Y, N8 C; l! u _; X5 Q
[rowsize,~]=size(SY);, H/ F. c. o7 e+ d; V
for i=1:rowsize
8 ~; Q% V2 A. v x ~ shsst(STR1{i},STR2{i},C,SY(i),WriteObject,im,txt)
( t, X g6 Q- ~8 i$ R$ v end
" ~6 z$ L, |# b7 s; R0 i: ~! n
1 g6 z9 |9 O& l hold off" w- S( O8 X$ X5 d5 E. V
close(WriteObject)
8 X7 J$ [) B4 W9 Y8 c %%% y0 N$ r# _% r" f Q# v
functioncbar()Tem=(-10:5:35);8 X: z- Q5 Y( q7 P
labcell=cell(1,10); %用于存储colorbar标签
& i4 K/ b- b; ? j+ X; y* ^( o. x for i=1:108 ~$ ~8 S6 k5 j1 b
labcell(i)={[${,int2str(Tem(i)),\,}^oC$]};
- a8 |$ h6 N5 @- G) {$ A end
6 g% R) \! @; ~ cb=colorbar;8 U; o: q y6 v; B. b: T6 ?: j. I
cb.TickLabelInterpreter=latex; %设置colorbar的刻度标签解释器为latex
) f* U, T0 B4 f' _% c+ z% x cb.TickLabels=labcell;+ H: q% E# C. n% z) }) i
cb.FontSize=12;
' }# C6 A6 e) E8 F- x end0 _% o3 Q( c. m. {
0 I( Q- ^' v# f6 m
functionshsst(str1,str2,C,sy,WriteObject,im,txt )load([str2,.mat],str1);" Y( f4 w3 a- _( w& P) P) E7 j
eval([[n1,~]=size(,str1,);]); %利用eval()函数执行文本代表的语句
- K0 g# b, {7 R0 W n1=n1/181-1; %数据每181行是一个月的全球SST数据% ?0 K* ]8 M/ \1 D. y, _+ @
for i=0:n1
8 q( Y) X/ k: S% l9 t+ B) H1 K eval([C(:, =,str1,(2+181*i:181+181*i,1:360);]);
( z' ?( i$ M( R( { C(C==-32768)=NaN;2 X, \5 x1 O% t9 Y
set(im,CData,C); %更新im的CData属性
2 e8 F) S8 ^8 m6 A! b/ v set(im,alphadata,1-isnan(C).*0.9); %利用isnan()函数标出NaN的位置并修改相应位置图形的透明度6 s3 F7 I+ l; {# G* b
set(txt,String,[int2str(sy+floor(i/12)),-,int2str(mod(i,12)+1)]); %更新文本
* c% e0 d+ w. _ R1 [
: z1 m8 _0 s" P L' w frame=getframe(gcf); ? L) ~( m7 |
writeVideo(WriteObject,frame);
; I7 R* p& W+ o; d- U end
: n$ G) J* W6 ] eval([clear ,str1]);0 Z* Q& E1 U% U
end, A8 D$ u: l2 ^' l, t
9 o) |" Q( P! Z- S' ^. K' d
效果图:: a3 H; M4 @) G; g
7 ]+ N3 X; G7 b1 Y6 Z
数据来源网站:
# X+ k2 K" K6 h2 \" r9 _ 1 s4 [ k$ P) J( \0 Q
(引用声明: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 p5 i- [# i5 \& v! i: Q2 Y3 f& R) j 代码中使用的文件数据都是我已经处理好的,如果自己导入数据的话记得修改代码对应位置的文件名和变量名。这是我导出完成的mat文件:
; }' ^" S& [% v6 N3 t 9 ^% ?3 t _3 I/ W1 Y
提取码8xt8。 2021.2.2更新有小伙伴私信问我那么一大堆数据具体是代表了个啥,在这里解释一下:原始数据是每181行储存了一个月的全球海洋表面温度数据,其中第一行是年月等信息,后面180行是180*360的矩阵,是将世界地图分成了180*360个小块,每一个数值大小代表了所在小块的温度,其中-32768代表陆地。(P.S.我看地图最北边越过陆地那块很多数值只是-1000或者-180,这是为啥我也不太清楚)
8 A) A q2 N: g- i, ` 参考文献: 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
8 W: ?+ u0 }; m ?9 d% a% K; H& g% g; q1 w. a
U" ~" Q/ z& E4 B7 C& W$ i$ R) t9 Y) |7 J6 F: n0 u
4 y' p# d% n5 E3 o; z6 N1 I |