|
0 y2 a* ?' C* n- [
最近准备参加美赛,队伍拿了2020年美赛A题磨合。得到数据后我便在想着怎么把图做得好看点,不得不说matlab作为商业软件这方面确实好用,使用imagesc()函数便可以非常好地实现我的目的。 1 F8 m u" C! Z/ k1 L0 h* L
matlab程序代码:
2 |9 D$ V/ P* m! S7 F- I1 k$ a %对图窗属性进行初始化" o7 P6 \/ d F2 C' Y ^
figure1 = figure(1); %创建图窗并获取图窗句柄
7 A. l" r @% p( B+ {9 s SIZE=get(0); %获取显示屏信息" X) j+ j2 T; m$ a
set(figure1,outerposition,SIZE.ScreenSize); %设置图窗位置和外部尺寸为显示屏大小
0 C( V# c+ T5 h1 n8 W C=zeros(180,360); %预分配内存$ q9 k) n8 f- Z8 Y; P
SY=zeros(22,1); %用于存储每一份数据的起始年份: X, p7 C+ V5 o" Z5 r1 o& X B
STR1=cell(22,1); %用于存储变量名. U5 {2 U" J# ?
STR2=STR1; %%用于存储文件名# B2 M) x1 Q3 {/ R! }( |
clim=[-1000,3500]; %设定imagesc的数值范围
# z+ ?. B4 x& d. k im=imagesc(C,clim); %创建image初始对象
" N/ X+ X4 C& ?- y T3 H colormap(jet); %指定颜色映射类型为jet
* e2 h1 P( Q' e Y9 p6 n; Q0 @ txt=text(320,175,0,," FontSize" ,20); %初始化一个text对象,用于显示年份和月份
& e& |, L+ T) Q( t7 k& \+ d title(Sea Surface Temperature (From 1870.1 to 2020.11),Interpreter,latex,FontSize,20);, l5 w' U$ Y. v v7 h7 |# p
axis off
0 C T3 R) o( Q% `8 Y hold on* k+ U! b: P3 e Q8 r5 S# f, d
cbar(); %显示预先设定的colorbar
7 d. |, }8 i- {& N- @3 w& K %%
( u2 k2 G: t, M6 g. U( e1 D filename = SST.mp4;
( ]& K& H+ J3 j( g% |8 J& C fps=10;
+ v! T0 G% K: \7 f ` WriteObject=VideoWriter(filename,MPEG-4); %创建视频写入对象
3 c$ S8 a5 C! D WriteObject.FrameRate=fps;
% k4 H x4 K" j& [ WriteObject.Quality=100;, N& w. t- A {, Z# v
open(WriteObject);
5 Y- q3 N' x* T, i8 N3 O# x- ~8 b9 x %%" `% f1 O: _, B
SY(1:5,1)=[1870 1901 1931 1961 1991];
5 j$ t+ `, Q4 g2 u8 e2 K4 W STR1(1:5,1)={HadISST1SST18701900,HadISST1SST19011930,HadISST1SST19311960,HadISST1SST19611990,HadISST1SST19912003};4 Z) {" q3 s2 {' V" r
STR2(1:5,1)={SST1870_1900,SST1901_1930,SST1931_1960,SST1961_1990,SST1991_2003};
& D+ M2 {) g9 @. a6 c" N for m=4:19: l9 u. v; t$ ~' d: v
sy=2000+m;
- a5 Q7 t" N3 U/ R str1=[HadISST1SST20,num2str(m,%02d)];
% m# A% W1 n; C F S& { str2=[SST20,num2str(m,%02d)];
( ~! N! f+ O: Q9 z- k$ |: s0 [ SY(m+2,1)=sy;9 @# U+ T. X5 V* }5 X+ q
STR1(m+2,1)={str1};6 s! W4 d$ M+ B( C. B5 l+ N
STR2(m+2,1)={str2};9 `6 V/ W$ _9 [. j! e
end
/ Q) A, E# V3 Q SY(end)=2020;
2 m; v8 y: s+ ` STR1(end)={HadISST1SST1};
! Z" G2 M- @, c8 S$ Y) _7 p8 m/ R. } STR2(end)={SST2020};: l+ {$ ], J, H' _. t) Z2 u" H
# e2 ]4 v0 k! `$ ^3 n, t3 b
[rowsize,~]=size(SY);: _: O, E% E2 w' V8 h: Z
for i=1:rowsize$ H# Q$ N5 E& E T9 d" h, p- f8 t9 L
shsst(STR1{i},STR2{i},C,SY(i),WriteObject,im,txt)* C( V# h2 Q4 O% W) U" O
end
# z* w( f+ e3 R; P. `2 ]: o
% P W3 K$ n1 D hold off5 t3 ^+ O: G T) J2 a
close(WriteObject)
* y2 v$ x& [- _% r, P: p5 A %%% ^9 H+ @+ W# `4 E- V
functioncbar()Tem=(-10:5:35);
' t" j2 K. h6 l4 d( u8 a- k5 V2 F- A labcell=cell(1,10); %用于存储colorbar标签. m) E2 i( d g1 _2 r r& D
for i=1:10
+ J+ d" M0 @& F3 k/ r: I6 Y. w6 T5 t/ \ labcell(i)={[${,int2str(Tem(i)),\,}^oC$]};
: n- H& ^3 K0 a9 B& Z end
& M8 X7 H8 i: C1 f cb=colorbar;
7 ?" s% s8 V; s5 n9 \8 F cb.TickLabelInterpreter=latex; %设置colorbar的刻度标签解释器为latex- X+ p# S8 V* p; C# E
cb.TickLabels=labcell;
! o! N- t* I: ?" T X5 G cb.FontSize=12;/ E0 l, W7 i: X+ Q4 n) ^
end
4 i a; n g8 T+ B. H! B8 x8 ?0 Q# {; R- u3 `) S ^. I
functionshsst(str1,str2,C,sy,WriteObject,im,txt )load([str2,.mat],str1);6 e# v9 j* R5 R
eval([[n1,~]=size(,str1,);]); %利用eval()函数执行文本代表的语句! c4 |- R, p1 w1 H) n& d l
n1=n1/181-1; %数据每181行是一个月的全球SST数据/ W0 |2 H# t9 o) T
for i=0:n1
$ L. c4 S2 e, e eval([C(:, =,str1,(2+181*i:181+181*i,1:360);]);: S% L+ s3 c2 Q2 w% e3 p
C(C==-32768)=NaN;
P0 W' x* ^7 t5 m$ Z- W: ]% ~: N set(im,CData,C); %更新im的CData属性
! C( n; Y6 x+ a- t7 ?3 f+ {- T set(im,alphadata,1-isnan(C).*0.9); %利用isnan()函数标出NaN的位置并修改相应位置图形的透明度) S6 a( g# [0 M& v2 L
set(txt,String,[int2str(sy+floor(i/12)),-,int2str(mod(i,12)+1)]); %更新文本
% H$ Y+ \4 ~# o7 k. k4 C3 m. a; ]" q
! K7 s* G+ I; \3 U" g* w0 Z frame=getframe(gcf);
, c& j |& T9 m2 {9 {- j writeVideo(WriteObject,frame);
l# w! N2 R. p. o9 {! H end8 ^6 `. S @/ {+ a: K& U. w3 L! Q
eval([clear ,str1]);
3 `4 m% \9 t/ X* g9 L3 X5 {( A end: I) A% T: l) I# g- M4 P! M
* Q# L% t+ u- d
效果图:9 b( _* d) Y2 o# I, |
( Y: u6 b# x3 f( @' l9 }+ n
数据来源网站: + E, ?% J: ~! Q# V" n1 o7 k
9 c# _0 B3 a. j: @) E! y1 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/)
. E5 y- i& s4 p* _! v F" @! t. A 代码中使用的文件数据都是我已经处理好的,如果自己导入数据的话记得修改代码对应位置的文件名和变量名。这是我导出完成的mat文件: 0 U2 L! q9 d, r9 E- D
3 ~6 s7 u' K$ N$ H: T' l: G
提取码8xt8。 2021.2.2更新有小伙伴私信问我那么一大堆数据具体是代表了个啥,在这里解释一下:原始数据是每181行储存了一个月的全球海洋表面温度数据,其中第一行是年月等信息,后面180行是180*360的矩阵,是将世界地图分成了180*360个小块,每一个数值大小代表了所在小块的温度,其中-32768代表陆地。(P.S.我看地图最北边越过陆地那块很多数值只是-1000或者-180,这是为啥我也不太清楚)
" b3 f/ A6 F/ _9 ?2 a- l 参考文献: 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 O9 K [# E, ^ d/ B' o \5 D6 c. u- Z2 U
$ x) A- y1 ]7 |, p, u
/ x. l$ V2 t$ l$ k7 s W+ `! m
/ L) k* A; h' n |