x軸の値を表記転換するには?

ファイルのデータから日時情報を取り出し、グラフのx軸に設定するにはどうすれば良いでしょうか?
下記の質問の補足になります。
下記プログラムで、出したグラフを添付します。 ①10/13 0:00-23:59、②2016/10/15 13:00-13:10
このグラフは
x軸がデータ番号となっており、 データ数:512個で、最初の100個は背景光(無視)、 100番目が0[m]になります。
距離分解能は、15[m]なので、
#0~99 Background
#100 0[m]
#101 15[m]
#102 30[m]
....
#200 1500[m]
...
#500 6000[m]
..
#511 6165[m]
end となります。
そこで、 1.x軸について、データ番号から観測距離[m]に表記変換したい。 データ番号を100からスタートさせ、100→0,101→15,102→30 と表記を変更したい。 2.データセットが4つあるうちの、2,4番目のみ取得して、グラフに表示させたい。
の方法をお聞きしたいです。よろしくお願い致します。
if true
% code
end
DebugFiles = 'C:\Users\aboken\Documents\MATLAB\161015\*16A1513.0*';
%指定フォルダ内のファイルをリスト化 日にち指定
D = dir(DebugFiles);
% ファイルオープン
fid=fopen(D(i).name);
% ヘッダー読み込み
for k = 1:3
headers{k} = fgetl(fid);
end
% データセットの数を取り出し
third_header = sscanf(headers{3},'%f');
num_datasets = 4third_header(end);
% データセットのヘッダーを読み込み
datasetheader = {};
for k = 1:num_datasets
datasetheader{k} = fgetl(fid);
end
fread(fid,2,'uint8') % Read CRLF=13d 10d
% データセットのヘッダーに記載されたデータ分バイナリデータを読み込む
data = {};
for k = 1:num_datasets
dataheader_parsed = sscanf(datasetheader{k},'%d');
num_read = dataheader_parsed(4);
[data{k},cunt] = fread(fid,num_read,'long');
fread(fid,2,'uint8'); % Read CRLF=13d 10d
end
% データファイルのクローズ
fclose(fid);
% 行列に整形(各データの数が同じ場合は成功)
DataMat = [data{:}];
plot(DataMat)
hold on
end

5 commentaires

michio
michio le 2 Août 2017
Modifié(e) : michio le 2 Août 2017
時系列のデータが用意できれば plot 関数で対応可能なんですが、、取り扱っているデータに明るくないのでかなりの難題になっています。
データ数:512個で、最初の100個は背景光(無視)、 100番目が0[m]
と説明して頂いてますが、データ番号と日時には何らかの関係がありますか?
今回添付して頂いたのは、
  1. x軸:データ番号
  2. y軸:フォトン数(光子数)
を複数のデータファイル(複数の日付)から取得して重ね書きしたものと解釈していますが、新たに日時をx軸に設定した場合、、y軸は何になりますでしょうか?
x軸はデータファイルのこの部分、y軸はデータファイルのこの部分を使いたい、など明示的に指示頂ければ理解できるかもしれません。
Jiro Doke
Jiro Doke le 3 Août 2017
michio さんの言う通り質問がよく理解できません。現在のXデータの単位は [m] のようですが、Xデータを時間にしたいという理解でよろしいでしょうか。その場合の [m] と時間の関係性が分かりません。
手書きの図(スキャン)でもいいので、期待している図を見せていただけると分かりやすいのですが。
nknknknk
nknknknk le 3 Août 2017
申し訳ございません。 別の作業と混ざって、間違った質問をしてしまいました。 以下が今回の質問です。よろしくお願い致します。
①x軸について、データ番号から観測距離[m]に表記変換したい。 データ番号を100からスタートさせ、100→0,101→15,102→30 と表記を変更したい。
②データセットが4つあるうちの、2,4番目のみ取得して、グラフに表示させたい。
理解不能な質問になってしまい、申し訳ございませんでした。 ご確認よろしくお願い致します。
Jiro Doke
Jiro Doke le 4 Août 2017
お手数ですが、もとの質問を上記の正しい質問に書き換えていただけますか?nknknknkさんのアイコンの下に「Edit」というリンクがあるので、そこから修正してください。とりあえず回答は下にしておきます。
nknknknk
nknknknk le 4 Août 2017
修正いたしました。 ご忠告ありがとうございます。

Connectez-vous pour commenter.

 Réponse acceptée

Jiro Doke
Jiro Doke le 4 Août 2017

2 votes

新しい質問に対して回答します。
1. データ番号を100(正確には101 : MATLAB は1から数えるため)から15刻みで表記。
plot コマンドの前にx軸となるベクトルを定義すればできます。
% まず 0 ~ 511 までの 15 刻みのベクトルを作成し、そこから 100 のオフセットをひく
x = (0:15:511*15) - 100*15;
plot(x,DataMat)
2. データセットが 4 つあるうちの、2,4 番目のみ取得して、グラフに表示させたい。
if 構文を使って、2,4番目のみをプロット。1.の回答と合わせると
if (i == 2) || (i == 4) % i が 2 か 4 ならば
% まず 0 ~ 511 までの 15 刻みのベクトルを作成し、そこから 100 のオフセットをひく
x = (0:15:511*15) - 100*15;
plot(x,DataMat)
hold on
end

11 commentaires

nknknknk
nknknknk le 4 Août 2017
ご回答ありがとうございます。
1. 理解力が足りず、確認でお聞きします。 x軸に観測距離[m]、y軸にフォトン数にしたい(x軸が0のときy軸はデータ番号100の時の値)のですが、これでなりますか?
2.解決しました。
Jiro Doke
Jiro Doke le 4 Août 2017
実際にコードを実行して確認されましたか?私の解釈では正しいと思いますが、試されて期待通りの結果かをご確認お願いします。
nknknknk
nknknknk le 7 Août 2017
ご回答ありがとうございます。
1.解決しました。
2.データセットが 4 つあるうちの、2,4 番目のみ取得して、グラフに表示させたい。
データ→#1 Analog On #2 Photoncount On #3 Analog Off #4 Photoncount Off
について、データ2.4番目でグラフ(fig.①が期待するグラフ)作成するため下記プログラムを実行した結果、データ1.3番目と思われるグラフが出ました(fig.②)。
また、data{}の中身をdisplay{data(2)},display{data(4)}で確認したところ、0、0、0・・・ 686868、という結果でした。データを読み込めていない原因は考えられるでしょうか?
3.続けて、display(data)でdata配列を確認したところfig③となりました。実際のデータ構造はfig④のように、32ビット(4バイト)のデータが512個あるのですが、これは合っているのでしょうか。
長々と申し訳ございませんが、ご回答よろしくお願い致します。
if true
% code%ファイル名をフルパスごと取得
DebugFiles = 'C:\Users\aboken\Documents\MATLAB\161015\*16A1214.0*';
%指定フォルダ内のファイルをリスト化 日にち指定
D = dir(DebugFiles);
%最初の2つは'.'と'..'だから、i=3からスタート
for i=3:length(D)
% ファイルオープン
fid=fopen(D(i).name);
%display(fid)
%display(D(i).name)
% ヘッダー読み込み
for k = 1:3
headers{k} = fgetl(fid);
end
% データセットの数を取り出し
third_header = sscanf(headers{3},'%f');
num_datasets = third_header(end); %4
% データセットのヘッダーを読み込み
datasetheader = {};
for k = 1:num_datasets
datasetheader{k} = fgetl(fid);
end
fread(fid,2,'uint8') % Read CRLF=13d 10d
% データセットのヘッダーに記載されたデータ分バイナリデータを読み込む
data = {};
for k = 1:num_datasets
dataheader_parsed = sscanf(datasetheader{k},'%d');
num_read = dataheader_parsed(4); %512
[data{k},cunt] = fread(fid,num_read,'long');
fread(fid,2,'uint8'); % Read CRLF=13d 10d
end
fclose(fid);
DataMat = [data{:}];
%display(data{1}) %データの中身確認用
if (k ==2) || (k == 4)
% 行列に整形(各データの数が同じ場合は成功)
%0~511までの15刻みのベクトルを作成し、そこから100を引く
x = (0:15:511*15) - 100*15;
plot(x,DataMat)
hold on
end
end
title('2016/10/13 14:00-14:59')
%%このグラフは何を意味しているのか、x軸に時間を、y軸に何か、グラフの範囲設定
xlabel('Range[m]')
ylabel('Photoncount')
xlim([0 3000])
ylim([0 1.2*10^8])
end
Jiro Doke
Jiro Doke le 7 Août 2017
以前提案した
if (k==2) || (k == 4)
の方法はてっきり2番目と4番目の「ファイル」をプロットしたいのかと勘違いしてました。
各ファイルの2番目と4番目のデータセットを取り出すのでしたら、
DataMat = [data{:}];
の行を
DataMat = [data{[2 4]}];
に変更して先の if を取り除いてやればいいかと思います。
(注:データ無しで提案しているのでご自身で試して正確性を確認してください)
「また、data{}の中身をdisplay{data(2)},display{data(4)}で確認したところ、0、0、0・・・ 686868、という結果でした。データを読み込めていない原因は考えられるでしょうか?」のご質問に対してですが、なぜデータが読み込めてないとお考えでしょうか。
こういう時に役立つのは デバッグ機能です。このリンクにも説明がありますが、プログラムを中断したい場所にブレークポイントを追加してプログラムを実行すると、ブレークポイントの場所で一時停止します。
そこで、コマンドウィンドウやワークスペースを使って現在の変数や状況を1行1行確認することができます。例えば、コマンドウィンドウで
>> figure
>> plot(data{2})
と実行して、その時の data{2} をグラフで確認することができます。
このような作業をやることによって、ちゃんとデータが読み込めたか、どの行で問題が生じたか、などを確認することができます。
少し、手間はかかりますが、このようにすると大体のケースで確実に問題の行を特定することができます。それが分かりましたら再びこのフォーラムで質問してください。
nknknknk
nknknknk le 7 Août 2017
ご丁寧にありがとうございます。 ご回答ありがとうございます。
DataMat = [data{2 4}]では期待通りのグラフが表示されますが(fig①)、 DataMat = [data{1 3}]では値が0になります(fig②)
% データセットのヘッダーに記載されたデータ分バイナリデータを読み込む
data = {};
for k = 1:num_datasets
dataheader_parsed = sscanf(datasetheader{k},'%d');
num_read = dataheader_parsed(4); %512
[data{k},count] = fread(fid,num_read,'long');
%display(data{k}) データ内確認
fread(fid,2,'uint8'); % Read CRLF=13d 10d
end
の部分でdata{}の中身を表示しても、データ2番目と4番目の中身は0になりました。 しかし、1番目と3番目はしっかりデータが入っています。 元の記録ファイルの問題でしょうか。。
Jiro Doke
Jiro Doke le 7 Août 2017
はっきりとは分かりませんが特にデータセット番号に対して違った処理をしているようには見えないので、もしかしたら実際にちゃんと計測されていないかもしれません。すべてのファイルに対して同じような現象がみられるのでしょうか(1,3はデータがあり、2,4は0)?
可能であったらデータファイルを別の方法で中身を確認するのが良いでしょう。例えば、もとの計測器についてきたソフトとかで。
nknknknk
nknknknk le 7 Août 2017
データをチェックし直した所、計測データが記録されていませんでした。 お騒がせ致しました。 ご丁寧な対応、ありがとうございました。
nknknknk
nknknknk le 8 Août 2017
一つだけ追加で質問させてください。
DataMat を x^2(距離の2乗)で割ってグラフ表示させたいのですが、
plot(x,DataMat./x^2)
で実行すると、以下のエラーが出ます。
エラー ^
入力はスカラーと正方行列でなければなりません。
POWER を要素ごとに計算するには、代わりに POWER (.^) を使用してください。
エラーの発生場所 ReadFile2jou (line 44)
plot(x,DataMat./x^2)
どのように計算、どんな関数を使って行列サイズを調整するのでしょうか。
恐らく初歩的な質問で恐縮ですが、ご確認お願いします。
Jiro Doke
Jiro Doke le 14 Août 2017
エラーメッセージに書いてある通り ^ ではなく .^ を使います。
plot(x,DataMat./x.^2)
nknknknk
nknknknk le 15 Août 2017
ご回答ありがとうございます。 それは試したのですが、
エラー ./
行列の次元は一致しなければなりません。
エラーの発生場所 ReadFile2jou (line 44)
plot(x,DataMat./x.^2)
と同じようにエラーメッセージが出ます。 他にどのようなことが考えられるでしょうか。
Jiro Doke
Jiro Doke le 16 Août 2017
DataMat がベクトルではなくて行列であるのに気づきませんでした。
そのエラーは割り算や二乗するときは同じ大きさ(行x列)同士でなければならないというエラーです。 DataMat は行列で x はベクトルだからですね。こういう時は大きさが同じになるように複製などして揃えてあげる必要があります。例えば
plot(x,DataMat./(repmat(x(:),1,size(DataMat,2)).^2))
関数 repmat のドキュメントを確認してみてください。もし分かりづらい場合は以下のような簡単な例で試してみてください。
x = 1:5;
DataMat = rand(5,3);
plot(x,DataMat./(repmat(x(:),1,size(DataMat,2)).^2))

Connectez-vous pour commenter.

Plus de réponses (0)

Catégories

En savoir plus sur 行列および配列 dans Centre d'aide et File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!