|
; ?' z) h# @0 u5 u
最近准备参加美赛,队伍拿了2020年美赛A题磨合。得到数据后我便在想着怎么把图做得好看点,不得不说matlab作为商业软件这方面确实好用,使用imagesc()函数便可以非常好地实现我的目的。
) K. ?1 X( [+ x/ [% j matlab程序代码:. [0 C0 M9 J# }
%对图窗属性进行初始化
6 i, E4 r+ P: s) t) t figure1 = figure(1); %创建图窗并获取图窗句柄4 n `0 K8 {; t( A
SIZE=get(0); %获取显示屏信息' n+ B' Y9 T3 I) T6 G2 ^
set(figure1,outerposition,SIZE.ScreenSize); %设置图窗位置和外部尺寸为显示屏大小8 [ I3 c% L7 T
C=zeros(180,360); %预分配内存6 [5 F4 P$ N3 y( T& i1 w7 r3 [4 q
SY=zeros(22,1); %用于存储每一份数据的起始年份+ _6 d9 s- P- M' C5 _& V! d
STR1=cell(22,1); %用于存储变量名) w! Q/ g: h& x$ v8 S
STR2=STR1; %%用于存储文件名
! J8 T: ?0 V2 @* _4 c- Q; g clim=[-1000,3500]; %设定imagesc的数值范围' o8 e5 B4 t8 x
im=imagesc(C,clim); %创建image初始对象
& `1 b9 W% I' s( a1 ? colormap(jet); %指定颜色映射类型为jet
/ k* h/ U, f! { txt=text(320,175,0,," FontSize" ,20); %初始化一个text对象,用于显示年份和月份8 u3 d# T& D, y+ e5 i' V9 c
title(Sea Surface Temperature (From 1870.1 to 2020.11),Interpreter,latex,FontSize,20);+ c/ T( n* A+ L
axis off7 @3 i8 Z; Y* L# l3 m
hold on& P6 O) r# w {8 T% p V9 E
cbar(); %显示预先设定的colorbar
$ P$ @. }$ C$ q& u6 y- \7 [ X %%
5 z# J# |) P* ~% a, @ filename = SST.mp4;
( o2 L* C& D2 \% r( x+ I# u fps=10; d# k7 }+ @( |0 c: H
WriteObject=VideoWriter(filename,MPEG-4); %创建视频写入对象$ F r; |$ {1 ?( N7 l
WriteObject.FrameRate=fps;
7 w1 n q3 a9 q7 g WriteObject.Quality=100;
9 a: |8 K& U. U$ o open(WriteObject);
& \. \+ L' t" S# o4 Z %%# i) s+ y" T' x; t4 m) h' @ w# m
SY(1:5,1)=[1870 1901 1931 1961 1991];& o# S0 u, y0 O6 H3 T- W2 E
STR1(1:5,1)={HadISST1SST18701900,HadISST1SST19011930,HadISST1SST19311960,HadISST1SST19611990,HadISST1SST19912003};: U( F8 V) g/ T8 U R' Q- X6 E- G
STR2(1:5,1)={SST1870_1900,SST1901_1930,SST1931_1960,SST1961_1990,SST1991_2003};7 D! k* `1 R O( J5 c# m
for m=4:199 E: x$ ]* T- @
sy=2000+m;1 P! V; F: r3 f' b
str1=[HadISST1SST20,num2str(m,%02d)];
$ a& h6 W* M+ D* r str2=[SST20,num2str(m,%02d)];
" v! {& G" V; V3 F# U0 _! f/ E SY(m+2,1)=sy;
4 Y7 H; F/ k }8 \: J STR1(m+2,1)={str1};
! Y' s; {/ c: I4 K* M% Y STR2(m+2,1)={str2};
# H$ ?; Z# [9 p0 B2 l& e9 e, V end
8 D: @9 K' T% B5 v3 F* F$ F SY(end)=2020;% P/ s( X! _. ~5 Y, H+ a) C
STR1(end)={HadISST1SST1};. l6 }+ r& ~; ]% v4 M) _0 q) ?
STR2(end)={SST2020};
p0 ]' x; O- }% f! Q! q. @
3 m- j" l) F2 G9 L* {! ] [rowsize,~]=size(SY);
4 A" ~ V4 `% E9 E7 d+ R; s+ M for i=1:rowsize
: O7 ? _/ q) w3 p! T shsst(STR1{i},STR2{i},C,SY(i),WriteObject,im,txt)+ z2 q' {# M( _% \7 L
end
( _! I. U- B( |9 ?+ L# ^
' v5 v+ O9 L( _( x hold off
2 l1 t3 Y( L& Q1 C5 V close(WriteObject); v9 I8 S9 Z/ U. T" o, c
%%
2 p9 `2 r! ? w$ K8 V8 Q functioncbar()Tem=(-10:5:35);- f1 m3 A1 L d' C
labcell=cell(1,10); %用于存储colorbar标签
& ]8 S' X5 \: J; U* S for i=1:10
" n" D8 H7 A& j' M/ d labcell(i)={[${,int2str(Tem(i)),\,}^oC$]};
: a6 F; H, _# N' Y7 }$ z0 @ x end
. W6 M. B! {) v0 O% C( K cb=colorbar;
' o& q1 V# c6 p$ S3 k* Y cb.TickLabelInterpreter=latex; %设置colorbar的刻度标签解释器为latex
* L3 H/ H5 [" y; R( Y9 E cb.TickLabels=labcell;
) T# |4 O0 P( G! c* V cb.FontSize=12;! V8 U' }- Z/ O( D
end
1 n2 N: n, Z0 Q
3 [! H2 A- b$ m functionshsst(str1,str2,C,sy,WriteObject,im,txt )load([str2,.mat],str1);
* J: D0 X( O+ [. K: ^0 E& q O% i4 x eval([[n1,~]=size(,str1,);]); %利用eval()函数执行文本代表的语句( e& ~8 u( ^8 e3 V' u7 H; k
n1=n1/181-1; %数据每181行是一个月的全球SST数据
& _" U; j8 v1 Z* b4 [* W3 I, U( G1 v for i=0:n1
6 L2 X3 G8 u' V8 {3 X eval([C(:, =,str1,(2+181*i:181+181*i,1:360);]);
# r) w! x) J7 A' R0 a) x1 _ C(C==-32768)=NaN;5 b. W/ Q: W" g$ y
set(im,CData,C); %更新im的CData属性 _! K- V6 P/ B8 w5 w* m/ p) S
set(im,alphadata,1-isnan(C).*0.9); %利用isnan()函数标出NaN的位置并修改相应位置图形的透明度# \% c" o+ e1 e$ @0 }
set(txt,String,[int2str(sy+floor(i/12)),-,int2str(mod(i,12)+1)]); %更新文本
$ {4 ~/ E6 u0 I' f, v3 s6 X3 d2 D8 m* b% d, S9 {9 {) f0 V
frame=getframe(gcf);
/ m9 o# S! R5 m3 l4 y) m writeVideo(WriteObject,frame);, R/ A% G$ H: U& y: m5 b" M9 p
end
! [/ W) b& K7 m( Z! ] eval([clear ,str1]);! `: e! P5 G8 Y. l/ P( d- T
end
# y& h# @ i0 t% |3 P! p
/ h7 Y* F; i9 t: C 效果图:7 y; V0 P$ i5 k; _5 y2 i0 m
% k& i- ` R) \% k* h$ p3 _
数据来源网站:
4 r( R) S( O p* f5 I* v; q
5 d/ t1 ]) `/ F3 a8 E0 U# ~- l! [ (引用声明: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 i9 _. }; `& _+ ?' g1 ^ 代码中使用的文件数据都是我已经处理好的,如果自己导入数据的话记得修改代码对应位置的文件名和变量名。这是我导出完成的mat文件: ) _1 M, U6 I: z( f! g2 m1 P
4 ?( M; @3 `: ]* r, q3 c 提取码8xt8。 2021.2.2更新有小伙伴私信问我那么一大堆数据具体是代表了个啥,在这里解释一下:原始数据是每181行储存了一个月的全球海洋表面温度数据,其中第一行是年月等信息,后面180行是180*360的矩阵,是将世界地图分成了180*360个小块,每一个数值大小代表了所在小块的温度,其中-32768代表陆地。(P.S.我看地图最北边越过陆地那块很多数值只是-1000或者-180,这是为啥我也不太清楚)
% d$ Q6 S! R5 _; B0 y 参考文献: 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
1 g, A+ q7 ]# |8 M0 Y9 w: Z1 X! `$ j: ?2 N
G) C0 ~1 x6 B; N
% O& v2 E) X# b1 z
* q$ p0 g; j- g. Z6 g |