plotting data that includes '-nan(incl)'

Hi,
I have been gathering Data for experiments via .CSV files.
If the laser in the experiment is too far from a detector, the measurement at that time would, understandably, provide a 'nan'.
However, if this occurs, a function i wrote to convert .CSV data into arrays of doubles stops working, instead, it returns cells. I cannot plot these cells.
I guess the issue i am having is telling matlab to replace thoses nans with an arbitrarily large number or completely remove them and then provide me with a plottable Double array.
The Following Code contains: Csv2array function + 1 set of data plotting as expected + 1 set of data returning a cell type array rather than double:
clear all, clc, close all
%Mechanical Turbulance (Random) (Works as expected)
%T5
%Load data CSV
[T5nct, T5ncx1, T5ncy1, T5ncI1] = CSV2array("LF_BS_NC_Turb1.csv");
[T5ct, T5cx1, T5cy1, T5cI1] = CSV2array("LF_BS_C_Turb1.csv");
figure %Look at it
subplot(211)
plot(T5nct,T5ncx1, T5nct, T5ncy1, T5ct, T5cx1, T5ct, T5cy1)
legend({'NCx1(um)', 'NCy1(um)', 'Cx1(um)', 'Cy1(um)'}, 'location', "best")
title('Test 5: Random Turbulance, No Correction Vs Correction (x,y)')
xlabel('Time (seconds)');
ylabel('Distance From Centre (microns)');grid on, grid minor;
subplot(212)
plot(T5nct,T5ncI1, T5ct, T5cI1)
legend({'(NC)Intensity(Volts)', '(C)Intensity(Volts)'}, 'location', "best")
title('Test 5 (I(V))')
xlabel('Time (seconds)');
ylabel('Intensity (Volts)');
grid on, grid minor;
%T6: NC -> C in 2mins, random mechanical adjustment of FSM (Does not work
%as expected
%Load data CSV
[T6t, T6x1c, T6y1c, T6I1] = CSV2array("LF_BS_NC+CT6.csv");
%Matlab having a hissy fit, decides to convert to cell instead
T6x1=cell2num(T6x1c);
T6y1=cell2num(T6y1c);
figure %Look at it
subplot(211)
plot(T6t, T6x1, T6t, T6y1)
legend({'x1(um)', 'y1(um)'}, 'location', "best")
title('Test 6: Random Turbulance, No Correction Vs Correction (x,y)')
xlabel('Time (seconds)');
ylabel('Distance From Centre (microns)');grid on, grid minor;
subplot(212)
plot(T6t,T6I1)
legend({'(NC)Intensity(Volts)', '(C)Intensity(Volts)'}, 'location', "best")
title('Test 6 (I(V))')
xlabel('Time (seconds)');
ylabel('Intensity (Volts)');grid on, grid minor;
function [t, x, y, I] = CSV2array(CSV)
TableData = readtable(CSV); %Puts CSV into table
%separate into columns of interest
tt= TableData(:,1);
xt= TableData(:,2);
yt= TableData(:,3);
It= TableData(:,4);
%Turns each table into an array
t= table2array(tt)./1e3; %converts time to Seconds
x= table2array(xt);
y= table2array(yt);
I= table2array(It);
end
Error: Error using plot
Invalid data argument. (When trying to plot the cell array)
Blank plot when trying to use "cell2num"
I have tried many other things but these are rather convoluted in my head and i fear it would be rather lengthy and useless to try and find everything I have tried so i can list to you.
I hope everything has been layed out clearly,
Thanks

 採用された回答

dpb
dpb 2021 年 6 月 22 日

0 投票

Use tables; you'll get benefit of variable names and easier addressing for free...the "CT6" file that your function didn't read is imported cleanly by readtable other than you may want to clean up the variable naming convention to make them allowable MATLAB variable names...
>> tCT6=readtable('LF_BS_NC+CT6.csv');
Warning: Column headers from the file were modified to make them valid MATLAB identifiers before creating variable names for the table. The original column headers are saved in the
VariableDescriptions property.
Set 'VariableNamingRule' to 'preserve' to use the original column headers as table variable names.
>> head(tCT6)
ans =
8×11 table
ms X1_um_ Y1_um_ I1_V_ X2_V_ Y2_V_ I2_V_ RX1_V_ RY1_V_ RX2_V_ RY2_V_
__ ______ _______ _____ _____ _____ _____ ______ ______ ______ ______
0 48.262 -91.18 2.9 0.001 0 0.13 4.96 4.97 5.01 5.02
28 48.55 -91.118 2.91 0.001 0 0.13 4.96 4.97 5.01 5.02
38 48.583 -91.18 2.9 0 0 0.13 4.96 4.97 5.01 5.02
43 48.583 -91.18 2.9 0 0 0.13 4.96 4.97 5.02 5.02
53 48.583 -91.18 2.9 0.001 0 0.13 4.96 4.97 5.01 5.02
48 48.583 -91.18 2.9 0 0 0.13 4.96 4.97 5.01 5.02
74 48.583 -91.834 2.9 0 0 0.13 4.96 4.97 5.02 5.02
84 49.236 -91.18 2.9 0.001 0 0.13 4.96 4.97 5.01 5.02
>> sum(~isfinite(tCT6{:,:}))
ans =
0 93 93 0 0 0 0 0 0 0 0
>>
reads the data cleanly but shows there are the exepcted NaN elements for a couple of the variables. You can remove those for analyses; plot() will just ignore non-finite elements silently and leave gaps in the plot...
To plot, just use the variable names and cell-addressing to select the variables wanted--these names can be variables as well as constant cellstr() values shown here; that allows you to write a generic function to plot any variable or combination of variables desired simply by giving the wanted variables by name (a reason for cleaning up the naming convention some).
>> plot(tCT6{:,{'X1_um_','Y1_um_'}})
>> title('Test 6: Random Turbulance, No Correction Vs Correction (x,y)')
xlabel('Time (seconds)');
ylabel('Distance From Centre (microns)');grid on, grid minor;
>>
results in

8 件のコメント

louis ferreira
louis ferreira 2021 年 6 月 22 日
Thank you! not sure i understand everything, but you've shown clear evidence it works.
louis ferreira
louis ferreira 2021 年 6 月 22 日
I think i understand now, essentially i was being inefficient by converting from table to doubles, when i could just extract the columns of choice as you have shown. Unfortunately, when i try this, I receive the error:
Error: error using plot
Invalid data argument
The code:
clear all, clc, close all
%T9: 3mins with tableslapper, NoCorrection then Correction
%Load data CSV
T9 = readtable("LF_BS_MECHTILT_T9.csv");
figure(1) %Look at it
subplot(211)
plot(T9{:, {'X1_um_', 'Y1_um_'}})
legend({'x1(um)', 'y1(um)'}, 'location', "best")
title('Test 8: 3mins with tableslapper, NoCorrection then Correction')
xlabel('Time (seconds)');
ylabel('Distance From Centre (microns)');grid on, grid minor;
subplot(212)
plot(T9{:, {'I1_V_'}})
legend({'Intensity (Volts)'}, 'location', "best")
title('Test 8 (I(V))')
xlabel('Time (seconds)');
ylabel('Intensity (Volts)');grid on, grid minor;
Having done this, i then tried what you did in the command window, as you can see from the attached screenshot, on my machine, it returns x1 and y1 values as strings rather than numeric.
I then tried the following:
plot(T9{:, {str2num('X1_um_'), str2num('Y1_um_')}})
but received the error:
A table variable subscript must be a numeric array containing real positive integers, a logical array, a character value, a string array, or a cell array of character vectors.
Thanks
louis ferreira
louis ferreira 2021 年 6 月 22 日
I should specify: the same occurs for T6, i just changed to T9 incase the issue was with the table itself
dpb
dpb 2021 年 6 月 22 日
I don't see any such behavior -- which release of MATLAB are you using? I have R2020b here; at some point TMW improved the built-in data scanning in readtable, but I don't know otomh with which release that was.
>> tT9=readtable('LF_BS_MECHTILT_T9.csv','VariableNamingRule','preserve');
>> head(tT9)
ans =
8×11 table
ms X1(um) Y1(um) I1(V) X2(V) Y2(V) I2(V) RX1(V) RY1(V) RX2(V) RY2(V)
__ _______ ______ _____ _____ _____ _____ ______ ______ ______ ______
0 -32.343 2.74 3.08 0.001 0 0.13 4.96 4.97 5.01 5.02
28 -32.359 2.74 3.08 0.001 0 0.13 4.96 4.97 5.01 5.02
38 -32.359 2.74 3.08 0.001 0 0.13 4.96 4.97 5.01 5.02
43 -31.732 2.74 3.08 0.001 0 0.13 4.96 4.97 5.01 5.02
53 -31.732 2.74 3.08 0.001 0 0.13 4.97 4.97 5.01 5.02
49 -31.749 2.74 3.08 0 0 0.13 4.96 4.97 5.02 5.02
74 -31.732 2.74 3.08 0 0 0.13 4.96 4.97 5.01 5.02
84 -31.732 2.429 3.08 0.001 0 0.13 4.97 4.97 5.01 5.02
>>
Try building an import options object and using it -- it was somewhat more robust earlier; if you must, you can forcibly set the variable types in it before calling readtable with the options object.
opt=readtable('LF_BS_MECHTILT_T9.csv','VariableNamingRule','preserve');
tT9=readtable('LF_BS_MECHTILT_T9.csv',opt);
and see if joy ensues....
louis ferreira
louis ferreira 2021 年 6 月 22 日
Thank you, may i please clarify what you mean by : "I see no such issue"
are you referring to in my screenshot or when you run it on your machine?
I am still on version 2019b
Thanks, i will try
dpb
dpb 2021 年 6 月 22 日
編集済み: dpb 2021 年 6 月 22 日
Running here I get the results I pasted in -- as noted, that's w/ R2020b; I no longer have an active license for earlier releases so can't easily check the differences. Pain, but so. I'm not positive whether I can associate the license with the earlier releases w/o counting against the number, so I've not tried it...
See what happens with the detectImportOptions route -- paste the top level result of the object or save it to a .mat file and attach so we can see what it reports. You're looking to see what
opt.VariableTypes
returns; it should be a cell string array of 'double'
The power in the import options object is, however, if for some reason detectImportOptions doesn't recognize a column as numeric, you can set the types as want them to be interpreted on your own and then pass the updated options object. Of course, to do this you have to resave the variable with the changes.
opt.VariableTypes=repmat({'double'},1,numel(opt.VariableTypes));
as example to set all to 'double' w/o worrying about which might have been something else specifically.
louis ferreira
louis ferreira 2021 年 6 月 24 日
thank you, sorry for not getting back to you quicker, the issue was resolved in 2019b by nesting a "str2num" in the plot function.
I should probably just update, this whole headache would have been avoided lol
Walter Roberson
Walter Roberson 2021 年 6 月 29 日
Activating an older release on a license on the same host as a newer release with the same license, does not increase the activation count for the license. The activation count is per-host, per-license, regardless of which release you are using.

サインインしてコメントする。

その他の回答 (0 件)

カテゴリ

ヘルプ センター および File ExchangeData Type Conversion についてさらに検索

製品

リリース

R2019b

Community Treasure Hunt

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

Start Hunting!

Translated by