|
" w0 _+ N( \. ?7 z 最近准备参加美赛,队伍拿了2020年美赛A题磨合。得到数据后我便在想着怎么把图做得好看点,不得不说matlab作为商业软件这方面确实好用,使用imagesc()函数便可以非常好地实现我的目的。 # I0 Q% ?* L, Y( m+ H! N" Y2 x: _
matlab程序代码:
) y8 ^2 ~4 s" d! x' p %对图窗属性进行初始化( S& b: o6 K: H4 V
figure1 = figure(1); %创建图窗并获取图窗句柄
0 ~/ V$ s) x7 E/ q SIZE=get(0); %获取显示屏信息! n# A& ~3 L' o. p# T
set(figure1,outerposition,SIZE.ScreenSize); %设置图窗位置和外部尺寸为显示屏大小
: e6 B3 S8 L7 _+ i; T C=zeros(180,360); %预分配内存
" ~0 H& ^- j+ c( o2 l" T/ F SY=zeros(22,1); %用于存储每一份数据的起始年份8 G/ W) a ?9 I8 o: L) M; C: ]
STR1=cell(22,1); %用于存储变量名
2 Z9 w% z. P% `8 ~: {, X) z STR2=STR1; %%用于存储文件名
! k: a- G1 r7 x9 t! p$ x" X clim=[-1000,3500]; %设定imagesc的数值范围
# [- z0 m, G7 |6 U" p9 \+ W0 K5 } im=imagesc(C,clim); %创建image初始对象
3 q4 l; F4 W' p, t) T( y2 g' D | colormap(jet); %指定颜色映射类型为jet6 R: F: P0 z+ V3 O3 [% G* O1 c
txt=text(320,175,0,," FontSize" ,20); %初始化一个text对象,用于显示年份和月份
" T m( l ~1 q4 W title(Sea Surface Temperature (From 1870.1 to 2020.11),Interpreter,latex,FontSize,20);
% f( l1 R9 ?: t& ]1 [ axis off
! l0 P/ B, P7 y5 h3 z$ E) l hold on5 c, Y8 C# O) L
cbar(); %显示预先设定的colorbar2 l2 J h5 S$ o$ P7 C0 S5 P
%%6 g6 i4 L7 k, A4 \$ ^
filename = SST.mp4;- g2 f. R% t' l
fps=10;
3 R( y2 j" Q0 t; n& Q- T WriteObject=VideoWriter(filename,MPEG-4); %创建视频写入对象) i/ O2 k( @( U
WriteObject.FrameRate=fps;6 {% ~6 }& b6 a. Y D, _; _# }, Z
WriteObject.Quality=100;
/ ~- T# V( e+ l8 w1 X" G open(WriteObject);
/ s3 \% q* U6 w7 w7 y4 k3 X) | %%8 G0 j% e8 C$ U' O- ~
SY(1:5,1)=[1870 1901 1931 1961 1991];6 U8 X, @; A; z: F8 `- P
STR1(1:5,1)={HadISST1SST18701900,HadISST1SST19011930,HadISST1SST19311960,HadISST1SST19611990,HadISST1SST19912003};
5 u0 B; @4 r2 i STR2(1:5,1)={SST1870_1900,SST1901_1930,SST1931_1960,SST1961_1990,SST1991_2003};
9 f! F+ X+ |# q' o% t. | for m=4:19
! f5 l' r. B. g* r8 D0 c sy=2000+m;% f v0 v8 m. @# R2 W7 s n8 Y c
str1=[HadISST1SST20,num2str(m,%02d)];
% k) p- S' `+ i7 J+ [* ] str2=[SST20,num2str(m,%02d)];
# b( u# f0 N4 A3 U, c* |% @2 R& v SY(m+2,1)=sy;
7 h. y/ P B) m+ f6 P: n' | STR1(m+2,1)={str1};9 t& e8 V7 r" b! ~
STR2(m+2,1)={str2};
. E4 S# k6 f9 g v" U* }- i0 J end/ S1 b- C$ G. \8 ?& j7 v& m `0 C
SY(end)=2020;, y5 N0 o3 Y9 g& Q4 f5 k! _
STR1(end)={HadISST1SST1};
9 R2 ~1 }# F, U4 {" e STR2(end)={SST2020};
) g, Z v B: Z! l3 n
. w0 _' O$ X6 P7 } [rowsize,~]=size(SY);: q; ^/ a8 `3 m2 A6 `
for i=1:rowsize
+ O; {5 Q9 f# S9 z u0 }" w shsst(STR1{i},STR2{i},C,SY(i),WriteObject,im,txt)3 W9 z& k4 f3 w0 T* B2 V
end5 A+ T/ S3 S* m! b2 y0 B% S
& R F& ~3 _1 J1 w% U* j hold off8 b* Q- i% o$ w( U5 w L% S, V
close(WriteObject)
5 R8 a" \8 ~# p0 X2 T %%
8 {, K8 D D% z functioncbar()Tem=(-10:5:35);$ N- n) |; c3 f# w% e
labcell=cell(1,10); %用于存储colorbar标签
2 x3 \, F9 Z6 b) K for i=1:10
. c X' \4 i8 ~& b labcell(i)={[${,int2str(Tem(i)),\,}^oC$]};
4 l+ Y' R6 O/ U h2 ? end+ S' z! h5 Z' C L6 U9 i* ~" n
cb=colorbar;( {6 u9 Y0 o7 M# u) x- Z. b
cb.TickLabelInterpreter=latex; %设置colorbar的刻度标签解释器为latex
8 Z- ]3 {: g' U8 R% x" H" M cb.TickLabels=labcell;
+ W) {- ?# V9 G3 U( G* y# Z% P cb.FontSize=12;5 O) H9 a* e4 z6 m% g
end
% J& ]4 w) l, p! R% f% @% L& o' a k) Z3 ^
functionshsst(str1,str2,C,sy,WriteObject,im,txt )load([str2,.mat],str1);
( K( D( }! F1 j7 x5 C eval([[n1,~]=size(,str1,);]); %利用eval()函数执行文本代表的语句
+ P9 b0 m, l4 u9 k2 | n1=n1/181-1; %数据每181行是一个月的全球SST数据
% ~4 R* R4 c4 b9 P: d# e" o for i=0:n12 d' h# e# h; v7 F+ K G; u% P$ P/ v
eval([C(:, =,str1,(2+181*i:181+181*i,1:360);]);" J, |' D5 M6 b% X- t
C(C==-32768)=NaN;. s/ ?: G9 G, Q) K5 O+ V
set(im,CData,C); %更新im的CData属性$ P" q n( D6 Y2 w% U; G8 L, w
set(im,alphadata,1-isnan(C).*0.9); %利用isnan()函数标出NaN的位置并修改相应位置图形的透明度
! r9 U6 Q m5 y set(txt,String,[int2str(sy+floor(i/12)),-,int2str(mod(i,12)+1)]); %更新文本0 R! ~: y. x% R' p% v, H0 `! @/ U
, Z7 z0 Z0 b& d frame=getframe(gcf);( `& g) N, J, V; f& \; N% d. m7 G$ U
writeVideo(WriteObject,frame);) e5 M! f$ ^# O4 H
end
- f9 w& d0 {& S3 s# w5 I eval([clear ,str1]);
% m8 m' L% H/ @ M end
5 a. }- P/ L2 L: B0 ~( ~3 ^
' P# |6 W/ r" a 效果图:
( U8 J6 S w$ t0 T
7 V/ u+ o* E; p% W4 g; D 数据来源网站: ! Q) F+ P( ]5 G' d
3 V' a( H) _* p1 P
(引用声明: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/) ( |: r- ^- s+ v! m J
代码中使用的文件数据都是我已经处理好的,如果自己导入数据的话记得修改代码对应位置的文件名和变量名。这是我导出完成的mat文件: - i1 i& w5 r0 L$ U
# I8 k! [/ _! h$ Z G- j 提取码8xt8。 2021.2.2更新有小伙伴私信问我那么一大堆数据具体是代表了个啥,在这里解释一下:原始数据是每181行储存了一个月的全球海洋表面温度数据,其中第一行是年月等信息,后面180行是180*360的矩阵,是将世界地图分成了180*360个小块,每一个数值大小代表了所在小块的温度,其中-32768代表陆地。(P.S.我看地图最北边越过陆地那块很多数值只是-1000或者-180,这是为啥我也不太清楚) % [3 b d! i2 v/ V
参考文献: 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
/ k( _! K& L" k" O: R4 i! B& j9 t- b h7 {) T' h' o
& \2 q9 c; N2 I% S% w) u5 T
1 E7 G, Q# y% W- F: B
: h9 w7 f9 I6 @4 ` |