2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

GOSAT(いぶき)のデータをMATLABで解析

Last updated at Posted at 2025-11-16

大学時代は気象学会所属で大気データの解析をする研究だったので、この分野をMATLABでやったらどんな感じだろうということでやってみました。

GOSAT(愛称:いぶき)とは

温室効果ガス観測技術衛星「GOSAT (Greenhouse gases Observing SATellite)」は、JAXA・環境省・国立環境研究所の共同プロジェクトとして2009年に打ち上げられた衛星で、主に二酸化炭素(CO₂)とメタン(CH₄)などの温室効果ガスを観測しています。

今回扱う「L3 CH₄データ」は、GOSATが観測したメタン濃度の結果をもとに、2.5度メッシュで月平均のカラム濃度をグリッド化しているデータです。

この投稿では、HDF5形式で提供されるL3 CH₄データをMATLABで読み込み、可視化する手順を紹介します。衛星観測データに興味がある方や、MATLABでの衛星データ処理に挑戦したい方の参考になれば幸いです。

image.png
こういうのができます!

GOSAT L3 CH₄データの入手方法

GOSATのデータは、国立環境研究所が運営する公式データ提供サイトGOSAT Data Archive Service(GDAS) から無料で入手できます。

公開されているのはCO₂とCH₄のざっくり以下のデータです。
L1…生のスペクトル・輝度データ
L2…観測から導出されたCO₂・CH₄の濃度など
L3…L2データを空間・時間でグリッド化したもの
L4A…フラックス(排出・吸収量)の推定結果
L4B…L4Aを使った濃度分布のシミュレーション結果

L1データは私のような素人には扱えず、L2データも可視化が大変なので、今回はCH₄のL3データを使います。
日本の衛星だけあってデータ説明書の日本語版があるのがとても嬉しい。

なお、今はCOGデータなる便利なものがTellusで公開されているようですが、今回はGDASから入手したデータを使います。
(パッと見ただけで便利すぎてこの記事いらない気もしてきましたが…)

解凍

まずはとってきたtarファイルを解凍します。
MATLABにはuntarというtar解凍コマンドがあるのでそれを使います。

% 対象フォルダのパス
sourceFolder = "tarファイルがあるパスを入力";

% .tar または .tar.gz ファイルの一覧を取得
tarFiles = dir(fullfile(sourceFolder, "*.tar*"));

% 解凍したファイルを集めるフォルダ
outputFolder = fullfile(sourceFolder, "all_files");
if ~exist(outputFolder, "dir")
    mkdir(outputFolder);
end

% 解凍ループ
for k = 1:length(tarFiles)
    tarPath = fullfile(sourceFolder, tarFiles(k).name);
    
    % 解凍実行
    untar(tarPath, outputFolder);
end

複数のtarファイルをダウンロードした場合も、同じフォルダにtarファイルを集めて上記を実行すれば解凍できます。
all_filesというフォルダにSWIRL3CH4というフォルダができ、その下にHDF5(.h5)ファイルが並んでいるはずです。

データの確認&前処理

次はh5ファイルのデータ構造を確認します。
h5infoという関数でHDF5ファイルの構造がわかるのですが、下記を実行したところデータ構造が入っているのが
info.Groups(2).Groups
の下だったのでちょっとわかりにくいかも。

% データファイルが入っているフォルダ
dataFolder = "h5ファイルがあるパスを入力"; 

% 読み込むファイル名
fileName = "なんでもいいのでh5ファイルを一つ選んでファイル名を入力";

% フルパスを作成
flfname = fullfile(dataFolder, fileName)

info = h5info(flfname);

上記の実行結果のinfoを掘っていくか、公式ドキュメントを確認すると、全球メタン濃度マップを描くのに必要なデータが以下にあることがわかりました。

メタン濃度データ(補正済み):/Data/mixingRatio/XCH4BiasCorrected
緯度:/Data/geolocation/latitude
経度:/Data/geolocation/longitude

データを変数に格納しましょう。

ch4 = double(h5read(flfname, "/Data/mixingRatio/XCH4BiasCorrected"));  % カラム平均濃度
lat = double(h5read(flfname, "/Data/geolocation/latitude"));
lon = double(h5read(flfname, "/Data/geolocation/longitude"));

このままマップを描いてしまうと
image.png
無効値のせいでこんなマップになってしまうので前処理が必要です。

ドキュメントを読むと無効値=-9999と書かれていますが、コマンドで探すときはsummary関数が便利です。

summary(ch4(:))

NumMissing 0
Min -9999
Median -9999
Max 1.9657
Mean -5.3555e+03
Std 4.9879e+03

今回は-9999が無効値なので、-9999をNaNに変換して再度マップ化します。

ch4(ch4 == -9999) = NaN; % 無効値を NaN に変換

figure; 
ax = axesm("MapProjection","robinson","Frame","on","Grid","on");
surfm(lat, lon, ch4);
colorbar;
title("GOSAT L3 CH_4 (ppmv)")

load coastlines  % 海岸線データが読み込まれる
geoshow(coastlat, coastlon, "Color", "k", "LineWidth", 1) % 海岸線を重ねる

image.png

できた!
ここで重要なのはaxesm関数とsurfm関数。
axesmで投影方法などを指定してベースのマップを作り、その上にsurfm関数でlat(緯度), lon(経度)に応じたメッシュに、ch4(濃度データ)の値に応じた色を付けています。
この2つだけであれば、あとは細かい調整をするだけです。

細かい調整

文字を見やすく

タイトルとカラーバーの文字が小さいので大きくします。

% タイトル文字を太字+サイズ16に指定
title("GOSAT L3 CH_4 (ppmv)", "FontWeight", "bold", "FontSize", 16) 
cb.FontSize = 12; % 目盛りの文字の大きさを指定

image.png

カラーバーを変える

デフォルトのカラーバー(parula)は赤系がなくて淡泊な感じなのでカラーバーを "jet" に変えてみます。
ついでに、今後のためにclimでカラーバーの範囲も固定しておきます。

colormap("jet"); % カラーマップをjetにする
clim([1.80 1.96]);   % カラーバーの範囲を固定

image.png

カラフルな図になりました。
どんなカラーバーが用意されているかは、こちらのチートシートを見ると手っ取り早いです。
最新のカラーバーはcolormaplistで確認できます。2025時点の最新ではnebula(青~ピンク)が追加されています。

マップの形を変更

今はaxesm関数で "robinson" (ロビンソン図法)が指定されています。
"eqdcylin"(等距円筒図法)に変えてみましょう。

figure; 
ax = axesm("MapProjection","eqdcylin","Frame","on","Grid","on"); % 等距円筒図法を指定
surfm(lat, lon, ch4); % CH4濃度を描画
cb = colorbar;
title("GOSAT L3 CH_4 (ppmv)", "FontWeight", "bold", "FontSize", 16) % タイトルを設定
cb.FontSize = 12; % カラーバーのフォントサイズを12に
colormap("jet"); % カラーマップをjetにする
clim([1.80 1.96]);   % カラーバーの範囲を固定

load coastlines  % 海岸線データが読み込まれる
geoshow(coastlat, coastlon, "Color", "k", "LineWidth", 1) % 海岸線を重ねる

image.png

平面的な図になりました。グリッドデータはこちらのほうがわかりやすいですね。
どんな投影方法があるかは、maps関数で確認できます。

1データ可視化のまとめ

Step1. とってきたTarファイルを解凍

※Tarファイルは1つのフォルダにまとめておく

% 対象フォルダのパス
sourceFolder = "tarファイルがあるパスを入力";

% .tar または .tar.gz ファイルの一覧を取得
tarFiles = dir(fullfile(sourceFolder, "*.tar*"));

% 解凍したファイルを集めるフォルダ
outputFolder = fullfile(sourceFolder, "all_files");
if ~exist(outputFolder, "dir")
    mkdir(outputFolder);
end

% 解凍ループ
for k = 1:length(tarFiles)
    tarPath = fullfile(sourceFolder, tarFiles(k).name);
    
    % 解凍実行
    untar(tarPath, outputFolder);
end

Step2. データひとつを指定して可視化

以下のコードで、dataFolderにh5ファイルが入っているフォルダパスを、fileNameに可視化したいファイル名を指定して実行すれば可視化できます。

% データファイルが入っているフォルダ
dataFolder = "h5ファイルがあるパスを入力"; 
% 読み込むファイル名
fileName = "可視化したいh5ファイルを一つ選んでファイル名を入力";

% フルパスを作成
flfname = fullfile(dataFolder, fileName)

% データを変数に格納
ch4 = double(h5read(flfname, "/Data/mixingRatio/XCH4BiasCorrected"));  % カラム平均濃度
lat = double(h5read(flfname, "/Data/geolocation/latitude"));
lon = double(h5read(flfname, "/Data/geolocation/longitude"));
ch4(ch4 == -9999) = NaN; % 無効値を NaN に変換

% マップを作成(可視化)
figure; 
ax = axesm("MapProjection","eqdcylin","Frame","on","Grid","on"); % 等距円筒図法を指定
surfm(lat, lon, ch4); % CH4濃度を描画
cb = colorbar;
title("GOSAT L3 CH_4 (ppmv)", "FontWeight", "bold", "FontSize", 16) % タイトルを設定
cb.FontSize = 12; % カラーバーのフォントサイズを12に
colormap("jet"); % カラーマップをjetにする
clim([1.80 1.96]);   % カラーバーの範囲を固定

load coastlines  % 海岸線データが読み込まれる
geoshow(coastlat, coastlon, "Color", "k", "LineWidth", 1) % 海岸線を重ねる

image.png

1年分を一気にマップ化

Step1. とってきたTarファイルを解凍

→上記同様なので省略

Step2. 1年分のデータを並べて可視化

以下のコードで変数yearに解析したい年、dataFolderにh5ファイルが入ったフォルダを指定すれば1年分のデータを可視化できます。
ファイル名が
GOSATTFTS[年][月]….h5
になっていたので、filenamesに1年分のデータ(12個)のファイル名を格納し、順次読んでいっているだけです。
プロットを並べるのにtiledlayout関数を使っています。

year = 2024;  % ← ここを解析したい年に変えればOK
dataFolder = "h5ファイルがあるパスを入力";  % データファイルのフォルダパス

pattern = sprintf("GOSATTFTS%d*.h5", year);

% FileDatastoreでHDF5ファイルを管理
fds = fileDatastore(fullfile(dataFolder, pattern), ...
    'ReadFcn', @readH5Data, ...
    'FileExtensions', '.h5');

% 今回は12か月分(小さい)なので全ファイルを読み込み
dataAll = readall(fds);

% タイルレイアウトの準備
figure;
tiledlayout(3, 4, "TileSpacing", "tight", "Padding", "tight");

% カラースケールの固定範囲
cmin = 1.80; 
cmax = 1.96;

% 海岸線の読み込み
load coastlines;

% 12か月分をプロット
for m = 1:12
    nexttile;
    axesm("MapProjection", "eqdcylin", "Frame", "on", "Grid", "on");
    surfm(dataAll{m}.lat, dataAll{m}.lon, dataAll{m}.ch4);
    title(sprintf("%02d月", m), "FontWeight", "bold", "FontSize", 14);
    clim([cmin cmax]);
    geoshow(coastlat, coastlon, "Color", "k", "LineWidth", 1);
end

% カラーマップとカラーバー
colormap("jet");
cb = colorbar;
cb.Layout.Tile = "east";  % 右端に配置
cb.FontSize = 12;

% 全体タイトル
sgtitle(sprintf("%d年の月別メタン濃度分布 (ppmv)", year), ...
        "FontWeight", "bold", "FontSize", 16);

%% --- HDF5読み込み関数 ---
function data = readH5Data(filename)
    ch4 = double(h5read(filename, "/Data/mixingRatio/XCH4BiasCorrected"));
    lat = double(h5read(filename, "/Data/geolocation/latitude"));
    lon = double(h5read(filename, "/Data/geolocation/longitude"));
    ch4(ch4 == -9999) = NaN;
    data = struct('ch4', ch4, 'lat', lat, 'lon', lon);
end

image.png

1年分マップ化できました!季節変化が見えていますね。

次回はもう少し深く解析していきたいと思います。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?