|
: }$ y* L& f$ q( n
最近准备参加美赛,队伍拿了2020年美赛A题磨合。得到数据后我便在想着怎么把图做得好看点,不得不说matlab作为商业软件这方面确实好用,使用imagesc()函数便可以非常好地实现我的目的。 + H. ^+ [2 {; @9 {
matlab程序代码:. R. z; U, i2 @7 s7 _' D
%对图窗属性进行初始化/ {$ i1 y L; o
figure1 = figure(1); %创建图窗并获取图窗句柄7 s( w- J, h* @2 X7 }2 y
SIZE=get(0); %获取显示屏信息
2 ]6 \; v# b1 h0 R5 c; r set(figure1,outerposition,SIZE.ScreenSize); %设置图窗位置和外部尺寸为显示屏大小
, e" b/ E) o& y) O% s( o, t T C=zeros(180,360); %预分配内存
9 u% n0 |0 s/ o6 H& t SY=zeros(22,1); %用于存储每一份数据的起始年份+ r7 e+ m' g5 f* e
STR1=cell(22,1); %用于存储变量名+ p6 J" m+ @! j$ M' C6 ?" l
STR2=STR1; %%用于存储文件名
% E0 C6 B5 h2 R8 H. O4 u clim=[-1000,3500]; %设定imagesc的数值范围
0 i" T1 N7 S9 ]9 G! z: U" I& r im=imagesc(C,clim); %创建image初始对象
$ d% p3 m4 L( G4 Q colormap(jet); %指定颜色映射类型为jet
/ ^8 m4 A1 Q0 V: [ txt=text(320,175,0,," FontSize" ,20); %初始化一个text对象,用于显示年份和月份
( k7 Z9 p, u8 f, y/ ? title(Sea Surface Temperature (From 1870.1 to 2020.11),Interpreter,latex,FontSize,20);. x7 ]- ]% b& e& n. U* k, A
axis off- s d: L9 R( G. H. ?- ?* b
hold on- m* `5 Q0 v3 _ v; k( i! n
cbar(); %显示预先设定的colorbar, J" L- a- K* V9 {8 v
%%
5 R# q& i$ ^+ E4 {$ ? filename = SST.mp4;
$ T5 j( s( b7 T, ^ fps=10;$ M" Z, g* W- n+ k4 w5 z5 t( @
WriteObject=VideoWriter(filename,MPEG-4); %创建视频写入对象
9 O' n" L7 V: T8 C WriteObject.FrameRate=fps;8 z" d! ?5 F! v; q% D
WriteObject.Quality=100;0 ^; c- z+ c- }" X# l% |7 [
open(WriteObject);
$ n& Q" T1 d: r %%
: {. q0 x3 X6 D8 q0 U$ R1 O SY(1:5,1)=[1870 1901 1931 1961 1991];+ j! d+ d% Q9 y, X
STR1(1:5,1)={HadISST1SST18701900,HadISST1SST19011930,HadISST1SST19311960,HadISST1SST19611990,HadISST1SST19912003};
, a, r) b4 n' X; t STR2(1:5,1)={SST1870_1900,SST1901_1930,SST1931_1960,SST1961_1990,SST1991_2003};
$ T% e0 i. v+ o! h$ f for m=4:197 W/ y" E$ [, h5 d( F$ ]
sy=2000+m;& t* _4 a, h3 ^. M( O4 M
str1=[HadISST1SST20,num2str(m,%02d)];$ }* g9 x' y4 p1 q' q3 v7 x
str2=[SST20,num2str(m,%02d)];
5 m# [5 O' J, ~$ {/ | SY(m+2,1)=sy;+ Q, `* a) {; ]9 Q& P" a
STR1(m+2,1)={str1};
' t6 F; g# H7 h* E6 l STR2(m+2,1)={str2};
. `$ a4 Q! c9 l end
+ `6 X5 `' K% b7 F! F! W SY(end)=2020;) |1 k( @1 c" B K: z
STR1(end)={HadISST1SST1};
9 f9 Y% }7 D( V2 a2 T5 ] STR2(end)={SST2020};& h; S5 [, p( V3 {- a
( E0 P2 H2 W3 d. c8 S W) a+ g, f% {
[rowsize,~]=size(SY);
) g, `, A7 H: A for i=1:rowsize
4 Z: ~* l2 {& X8 u: x& u* R shsst(STR1{i},STR2{i},C,SY(i),WriteObject,im,txt)# t! j6 L' F' K1 K
end/ z5 B, y h% g$ S$ Z8 G0 d
% T1 {2 J2 K, M3 R hold off: k0 s6 o/ J. m; z
close(WriteObject)
1 f' K# f, ~6 }+ r) Z4 ^8 |* w3 I %%
# \9 P _* e) A functioncbar()Tem=(-10:5:35);
5 n/ `+ a; e+ }5 M, S, Q labcell=cell(1,10); %用于存储colorbar标签' _1 Y4 Z Y, [' {* _! G, G- G
for i=1:108 J/ ?& n7 P+ U* n
labcell(i)={[${,int2str(Tem(i)),\,}^oC$]};
- R) o; n3 S$ F end
4 O; u4 k& M9 d/ z cb=colorbar;8 x0 m7 E$ J+ L
cb.TickLabelInterpreter=latex; %设置colorbar的刻度标签解释器为latex O/ ^3 a3 i) l& a0 o1 ~
cb.TickLabels=labcell;
- J* n* o2 _ r1 P/ Y) C: _+ } cb.FontSize=12;! U2 z( E1 g; J' {
end7 L+ |, z6 g$ n
& l* z6 d' A1 q! i" q/ t functionshsst(str1,str2,C,sy,WriteObject,im,txt )load([str2,.mat],str1);, N' P$ W2 N# ~: x# V) [2 r* v& ^# Q; `
eval([[n1,~]=size(,str1,);]); %利用eval()函数执行文本代表的语句
3 _4 c7 w" D. E1 @6 M$ x4 R" u n1=n1/181-1; %数据每181行是一个月的全球SST数据9 [5 T R, z, e5 P9 G% S$ v7 K
for i=0:n1
' c7 L6 Z0 L9 Q$ M$ k$ b9 n& n eval([C(:, =,str1,(2+181*i:181+181*i,1:360);]);% ]+ P$ o8 M: M1 C. x$ I l
C(C==-32768)=NaN;
2 N2 j$ Q. P) W( k- _. | set(im,CData,C); %更新im的CData属性, u9 Z5 _+ y9 c' ]# _' K5 M7 J
set(im,alphadata,1-isnan(C).*0.9); %利用isnan()函数标出NaN的位置并修改相应位置图形的透明度
7 J8 s- \6 K- H9 y9 j- ` set(txt,String,[int2str(sy+floor(i/12)),-,int2str(mod(i,12)+1)]); %更新文本0 f1 a+ I% Y: `! z0 J. a
) k2 `) c9 Q* K- _
frame=getframe(gcf);
. {- _: b q- i, } writeVideo(WriteObject,frame);4 ?# z& C$ k5 d# D+ x
end
( M& }" w$ Z8 r4 W1 E7 r eval([clear ,str1]);$ p% o4 V- s, Z
end9 [9 t/ `+ y! ?8 `' Q v9 w
( O# ^$ I/ n$ U! N# t$ z
效果图:
& C. `+ ]4 M1 b) h1 f
9 }! K+ j2 _- e' L 数据来源网站:
; }# v: K4 q: `% ^0 J
/ R0 ^( o9 K4 I (引用声明: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/)
9 v2 L. d& I7 _+ J- J r' ~+ I- [ 代码中使用的文件数据都是我已经处理好的,如果自己导入数据的话记得修改代码对应位置的文件名和变量名。这是我导出完成的mat文件: # Y( g9 `5 K" b5 |3 [& {& h
5 U4 m) u7 u7 O 提取码8xt8。 2021.2.2更新有小伙伴私信问我那么一大堆数据具体是代表了个啥,在这里解释一下:原始数据是每181行储存了一个月的全球海洋表面温度数据,其中第一行是年月等信息,后面180行是180*360的矩阵,是将世界地图分成了180*360个小块,每一个数值大小代表了所在小块的温度,其中-32768代表陆地。(P.S.我看地图最北边越过陆地那块很多数值只是-1000或者-180,这是为啥我也不太清楚) ) i, c1 p) M4 c9 ]1 Z: ]- C$ {. 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
5 a' a- M0 @7 u
$ ]2 {6 ~% ` T" _5 F" l8 l( J* S7 D, D6 q" w$ p+ M6 _1 ]
& s' x+ m9 J7 g- n; f
" n% Z% w2 R+ `, F7 a' j/ h. X
|