How to plot array on to map with lat and long? - matlab

I have a 360-by-180 array and what to plot on to geobasemap.
The 360-by-180 array is basically earth and the cells are the property at that given lat-long.
When I first plot it using contour(X) the axes are from 0-360 and 0-180.
Then I used
R = georasterref('RasterSize', [180 360], ...
'RasterInterpretation', 'cells', 'ColumnsStartFrom', 'south','RowsStartFrom', 'west', ...
'LatitudeLimits', [-89.5 89.5], 'LongitudeLimits', [-179.5 179.5]);
contourm(x,R)
created the plot with axes from -90 ~ +90 and -180 ~ +180
Then when I try to plot on a geobasemap, it overlays with the map that I called out because the maps are on degree coordinates like -90degree ~ +90degree and -180degree ~ +180degree.
It seems like MATLAB doesn't let these number coordinate and degree coordinate systems plot onto each other.
Is there any way to plot the 360*180 array onto a map with -90degree ~ +90degree and -180degree ~ +180degree coordinates?
0.03 0 0 0 0 0 0 0.03
0 0 0 0 0 0 0 0
NaN NaN 0 0 0 0 0 0
0.01 0.05 0.05 NaN NaN NaN NaN NaN
NaN NaN NaN NaN NaN NaN NaN NaN
0 0 0 NaN NaN NaN NaN NaN
NaN NaN 0.02 0 0 NaN NaN NaN
NaN NaN NaN NaN NaN 0 0 0
NaN NaN NaN NaN NaN NaN NaN 0.01
NaN NaN NaN NaN NaN 0 0 0
NaN NaN NaN 0.04 0 0 NaN NaN
NaN NaN 0.03 0 NaN NaN NaN NaN
0 0.02 0.03 NaN NaN NaN NaN NaN
0.01 NaN NaN NaN NaN NaN NaN NaN
The above is the small section of my array, because putting the full 180-by-360 array is too long and impossible so this section is all I can put.
But the full 180-by-360 array is just much more section of this example.

I have able to plot a 360-by-180 satellite track onto a map.
R = georasterref('RasterSize', [180 360], ...
'RasterInterpretation', 'cells', 'ColumnsStartFrom', 'south','RowsStartFrom', 'west', ...
'LatitudeLimits', [-89.5 89.5], 'LongitudeLimits', [-179.5 179.5]);
axesm('miller');
% geoshow('landareas.shp')
load coastlines
plot(coastlon,coastlat) % load coastlines
contourm(X,R,'LineWidth',3)
As for X is the 360-by-180 array/matrix

Related

histogram of signals gaps width (Matlab)

I am looking for algorithm (effective + vectorized) how to find histogram of gaps (NaN) width in the following manner:
signals are represented by (Nsamples x Nsig) array
gaps in signal are encoded by NaN's
width of gaps: is number of consecutive NaN's in the signal
gaps width histogram: is frequency of gaps with specific widths in signals
And the following conditions are fullfilled:
[Nsamples,Nsig ]= size(signals)
isequal(size(signals),size(gapwidthhist)) % true
isequal(sum(gapwidthhist.*(1:Nsamples)',1),sum(isnan(signals),1)) % true
Of course, compressed form of gapwidthhist (represented by two cells: "gapwidthhist_compressed_widths" and "gapwidthhist_compressed_freqs") is required too.
Example:
signals = [1.1 NaN NaN NaN -1.4 NaN 8.3 NaN NaN NaN NaN 1.5 NaN NaN; % signal No. 1
NaN 2.2 NaN 4.9 NaN 8.2 NaN NaN NaN NaN NaN 2.4 NaN NaN]' % signal No. 2
gapwidthhist = [1 1 1 1 0 0 0 0 0 0 0 0 0 0; % gap histogram for signal No. 1
3 1 0 0 1 0 0 0 0 0 0 0 0 0]' % gap histogram for signal No. 2
where integer histogram bins (gap widths) are 1:Nsamples (Nsamples=14).
Coresponding compressed gap histogram looks like:
gapwidthhist_compressed_widths = cell(1,Nsig)
gapwidthhist_compressed_widths =
1×2 cell array
{[1 2 3 4]} {[1 2 5]}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
gapwidthhist_compressed_freqs = cell(1, Nsig)
gapwidthhist_compressed_freqs =
1×2 cell array
{[1 1 1 1]} {[3 1 1]}
Typical problem dimension:
Nsamples = 1e5 - 1e6
Nsig = 1e2 - 1e3.
Thanks in advance for any help.
Added remark: My so far best solution is the following code:
signals = [1.1 NaN NaN NaN -1.4 NaN 8.3 NaN NaN NaN NaN 1.5 NaN NaN; % signal No. 1
NaN 2.2 NaN 4.9 NaN 8.2 NaN NaN NaN NaN NaN 2.4 NaN NaN; % signal No. 2
1 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN]' % signal No. 3
[numData, numSignals] = size(signals)
gapwidthhist = zeros(numData, numSignals);
for column = 1 : numSignals
thisSignal = signals(:, column); % Extract this column.
% Find lengths of all NAN runs
props = regionprops(isnan(thisSignal), 'Area');
allLengths = [props.Area]
edges = [1:max(allLengths), inf]
hc = histcounts(allLengths, edges)
% Load up gapwidthhist
for k2 = 1 : length(hc)
gapwidthhist(k2, column) = hc(k2);
end
end
% What it is:
gapwidthhist'
But I am looking mainly for pure Matlab code without any built-in matlab functions (like "regionprops" from Image Processing Toolbox)!!!
This is much more simple Matlab implementation but still not optimal (+ not vectorized):
signals = [1.1 NaN NaN NaN -1.4 NaN 8.3 NaN NaN NaN NaN 1.5 NaN NaN; % signal No. 1
NaN 2.2 NaN 4.9 NaN 8.2 NaN NaN NaN NaN NaN 2.4 NaN NaN; % signal No. 2
1 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN]'; % signal No. 3
signals
[numData, numSignals] = size(signals);
gapwidthhist = zeros(numData, numSignals);
gaps = zeros(numData+1,numSignals);
auxnan = isnan(signals);
for i = 1:numSignals
c = 0;
for j = 1:numData
if auxnan(j,i)
c = c + 1;
else
gaps(j,i) = c;
c = 0;
end
end
gaps(numData+1,i) = c;
gapwidthhist(:,i) = histcounts(gaps(:,i),1:numData+1);
end
gapwidthhist
Thanks to #breaker for help.
Any idea how to optimize (vectorize) this code to be more effective?
Here is a slightly more vectorized version that may be a bit quicker. I use Octave, so I don't know how much MATLAB's JIT compiler will optimize the inner loop in the other approach.
% Set up the data
signals = [1.1 NaN NaN NaN -1.4 NaN 8.3 NaN NaN NaN NaN 1.5 NaN NaN; % signal No. 1
NaN 2.2 NaN 4.9 NaN 8.2 NaN NaN NaN NaN NaN 2.4 NaN NaN; % signal No. 2
1 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN]'; % signal No. 3
signals
[numData, numSignals] = size(signals);
gapwidthhist = zeros(numData, numSignals);
gaps = zeros(numData+1,numSignals);
auxnan = ~isnan(signals); % We want non-NaN values to be 1
for i = 1:numSignals
difflist = diff(find([1; auxnan(:,i); 1])) - 1; % get the gap lengths
gapList = difflist(find(difflist)); % keep only the non-zero gaps
for c = gapList.' % need row vector to loop over elements
gapwidthhist(c,i) = gapwidthhist(c,i) + 1; % each gap length increments the histogram
end
end
gapwidthhist
Here's the program flow:
First, negate the auxnan array so that NaN is 0 and non-NaN is 1.
In the outer loop, pad each column with 1's on top and bottom to capture strings of NaN at the beginning and end of the signal.
Use find to get the indices of the 1 (non-NaN) elements.
Take the diff of the indices.
A diff of 1 means no gap and a diff greater than 1 gives the length of the gap plus 1, so subtract 1 from the diff result.
Use the results (indices) of find to get the values of the nonzero elements. These are the gap widths.
Now loop through the values and accumulate the results in the histogram. You might try replacing this inner loop with accumarray to see if that speeds things up any.
May be final solution:
signals = [1.1 NaN NaN NaN -1.4 NaN 8.3 NaN NaN NaN NaN 1.5 NaN NaN; % signal No. 1
NaN 2.2 NaN 4.9 NaN 8.2 NaN NaN NaN NaN NaN 2.4 NaN NaN; % signal No. 2
1 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN]'; % signal No. 3
signals
[numData, numSignals] = size(signals);
gapwidthhist = zeros(numData, numSignals);
auxnan = isnan(signals);
for i = 1:numSignals
c = 0;
for j = 1:numData
if auxnan(j,i)
c = c + 1;
else
if c > 0
gapwidthhist(c,i) = gapwidthhist(c,i) + 1;
c = 0;
end
end
end
if c > 0
gapwidthhist(c,i) = gapwidthhist(c,i) + 1;
end
end
gapwidthhist
Open question: how to modify the code where outer for-loop should be able to use parfor-loop?

reshaped elements in different positions relative to original array - matlab [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
a=randn(4,4,2,3)
a(:,:,1,1) =
0.5377 0.3188 3.5784 0.7254
1.8339 -1.3077 2.7694 -0.0631
-2.2588 -0.4336 -1.3499 0.7147
0.8622 0.3426 3.0349 -0.2050
a(:,:,2,1) =
-0.1241 0.6715 0.4889 0.2939
1.4897 -1.2075 1.0347 -0.7873
1.4090 0.7172 0.7269 0.8884
1.4172 1.6302 -0.3034 -1.1471
a(:,:,1,2) =
-1.0689 0.3252 -0.1022 -0.8649
-0.8095 -0.7549 -0.2414 -0.0301
-2.9443 1.3703 0.3192 -0.1649
1.4384 -1.7115 0.3129 0.6277
a(:,:,2,2) =
1.0933 -1.2141 -0.7697 -1.0891
1.1093 -1.1135 0.3714 0.0326
-0.8637 -0.0068 -0.2256 0.5525
0.0774 1.5326 1.1174 1.1006
a(:,:,1,3) =
1.5442 -1.0616 -0.1924 -1.4224
0.0859 2.3505 0.8886 0.4882
-1.4916 -0.6156 -0.7648 -0.1774
-0.7423 0.7481 -1.4023 -0.1961
a(:,:,2,3) =
1.4193 -0.8045 0.2157 0.7223
0.2916 0.6966 -1.1658 2.5855
0.1978 0.8351 -1.1480 -0.6669
1.5877 -0.2437 0.1049 0.1873
[d1 d2 d3 d4]=size(a);
aa=reshape(a,[],d4)';
b(:,:,1)=[0 0 1 0;0 0 0 0; 0 0 0 0 ;0 0 0 0]
b(:,:,2)=[0 0 1 0;0 0 0 0; 0 0 0 0 ;0 0 0 0]
bb=reshape(b,1,[]);
aa(:,find(~bb))=NaN;
c=reshape(aa,d1,d2,d3,d4);
c(:,:,1,1) =
NaN NaN NaN NaN
NaN NaN NaN NaN
NaN NaN NaN NaN
NaN NaN NaN NaN
c(:,:,2,1) =
NaN NaN 3.5784 NaN
NaN NaN -0.1022 NaN
NaN NaN -0.1924 NaN
NaN NaN NaN NaN
c(:,:,1,2) =
NaN NaN NaN NaN
NaN NaN NaN NaN
NaN NaN NaN NaN
NaN NaN NaN NaN
c(:,:,2,2) =
NaN NaN NaN NaN
NaN NaN NaN NaN
NaN NaN NaN NaN
NaN NaN NaN NaN
c(:,:,1,3) =
NaN NaN 0.4889 NaN
NaN NaN -0.7697 NaN
NaN NaN 0.2157 NaN
NaN NaN NaN NaN
c(:,:,2,3) =
NaN NaN NaN NaN
NaN NaN NaN NaN
NaN NaN NaN NaN
NaN NaN NaN NaN
Why are the nonnan elements in c in a different position relative to their position in the original array a?
I was expecting the output
c(:,:,1,1) =
NaN NaN 3.5784 NaN
NaN NaN NaN NaN
NaN NaN NaN NaN
NaN NaN NaN NaN
c(:,:,2,1) =
NaN NaN 0.4889 NaN
NaN NaN NaN NaN
NaN NaN NaN NaN
NaN NaN NaN NaN
c(:,:,1,2) =
NaN NaN -0.1022 NaN
NaN NaN NaN NaN
NaN NaN NaN NaN
NaN NaN NaN NaN
c(:,:,2,2) =
NaN NaN -0.7697 NaN
NaN NaN NaN NaN
NaN NaN NaN NaN
NaN NaN NaN NaN
c(:,:,1,3) =
NaN NaN -0.1924 NaN
NaN NaN NaN NaN
NaN NaN NaN NaN
NaN NaN NaN NaN
c(:,:,2,3) =
NaN NaN 0.2157 NaN
NaN NaN NaN NaN
NaN NaN NaN NaN
NaN NaN NaN NaN
When I make these changes to your code, the output matches your expected output:
a = randn(4,4,2,3);
[d1 d2 d3 d4] = size(a);
aa = reshape(a,[],d4); % <-- NOTE! no transpose
b = [0 0 1 0;0 0 0 0; 0 0 0 0 ;0 0 0 0];
b(:,:,2) = [0 0 1 0;0 0 0 0; 0 0 0 0 ;0 0 0 0];
bb = reshape(b,1,[]);
aa(find(~bb),:) = NaN; % <-- NOTE! swapped indexing
c = reshape(aa,d1,d2,d3,d4);
By transposing the array aa, and not transposing back later, all elements ended up in a different location.
Edit: #Sardar Usama makes a good point in the comment below. You can accomplish the same thing like this:
c = a;
c(repmat(~b,[1,1,1,3])) = NaN
(and probably on other ways too, e.g. he's suggesting multiplication which would accomplish the same thing.)

Surf plot does not display colors correctly

This is the graph I get
The values I have for the graph are all close to 1. So I expected the graph to be mainly in red. Why does it show in blue? What does this colour bar mean ? What does this graph actually mean?
Values are
Columns 1 through 10
0 1.0000 0 0 0 1.0000 NaN 0.8634 0.9872 NaN
0 1.0000 0 0 0 1.0000 NaN 0.8634 0.9872 NaN
0 1.0000 0 0 0 1.0000 NaN 0.8634 0.9872 NaN
NaN 0 NaN NaN NaN 0 NaN 0 0 NaN
0 1.0000 0 0 0 1.0000 NaN 0.8634 0.9872 NaN
0 1.0000 0 0 0 1.0000 NaN 0.8634 0.9872 NaN
NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
0 1.0000 0 0 0 1.0000 NaN 0.8634 0.9872 NaN
NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
What you see is one patch. And a patch by default just has one color, determined by the z-level of the first point used to create the patch.
To solve the problem interpolate the face color by using the according property.
surf(X,'FaceColor','interp')
Alternatively interpolate your data to fit a much finer mesh. And looking at your data, I'm not sure if if surf is the right choice at all.

Make a vector equal to another by filling 'NaN' without interpolation

I have a time stamp as follow.
Time =
243.0000
243.0069
243.0139
243.0208
243.0278
243.0347
243.0417
243.0486
243.0556
243.0625
243.0694
243.0764
243.0833
243.0903
243.0972
243.1042
243.1111
243.1181
243.1250
243.1319
243.1389
243.1458
243.1528
243.1597
243.1667
243.1736
243.1806
243.1875
243.1944
Now I have another two column vector.
ab =
243.0300 0.5814
243.0717 0.6405
243.1134 0.6000
243.1550 0.5848
243.1967 0.5869
First column is 'Time2' and second column is 'Conc'.
Time2 = ab(:,1);
Conc = ab(:,2);
Now I want to match 'Conc' based on 'Time2' with 'Time' but only filling with 'NaN'. Also 'Time2' is not exactly as 'Time'. I can use something like following
Conc_interpolated = interp1(Time2,Conc,Time)
but it does an interpolation with artificial data. I only want to match vector length by filling with 'NaN' in 'Conc' not with interpolated data.Any recommendations? Thanks
I try to guess what you want:
you have time vector A:
TimeA = ...
[243.0000;
243.0069;
...
243.1875;
243.1944];
and probably some data A:
DataA = rand(length(TimeA),1);
now you want to implement your second time vector B:
TimeB = ...
[243.0300;
243.0717;
243.1134;
243.1550;
243.1967];
and the according data:
DataB = ...
[0.5814;
0.6405;
0.6000;
0.5848;
0.5869];
finally everything should be merged together and sorted:
X = [ TimeA, DataA , NaN(size(DataA)) ;
TimeB, NaN(size(DataB)) , DataB ]
Y = sortrows(X,1);
results to:
Y =
243.0000 0.8852 NaN
243.0069 0.9133 NaN
243.0139 0.7962 NaN
243.0208 0.0987 NaN
243.0278 0.2619 NaN
243.0300 NaN 0.5814
243.0347 0.3354 NaN
243.0417 0.6797 NaN
243.0486 0.1366 NaN
243.0556 0.7212 NaN
243.0625 0.1068 NaN
243.0694 0.6538 NaN
243.0717 NaN 0.6405
243.0764 0.4942 NaN
243.0833 0.7791 NaN
243.0903 0.7150 NaN
243.0972 0.9037 NaN
243.1042 0.8909 NaN
243.1111 0.3342 NaN
243.1134 NaN 0.6000
243.1181 0.6987 NaN
243.1250 0.1978 NaN
243.1319 0.0305 NaN
243.1389 0.7441 NaN
243.1458 0.5000 NaN
243.1528 0.4799 NaN
243.1550 NaN 0.5848
243.1597 0.9047 NaN
243.1667 0.6099 NaN
243.1736 0.6177 NaN
243.1806 0.8594 NaN
243.1875 0.8055 NaN
243.1944 0.5767 NaN
243.1967 NaN 0.5869
is that right?
My understanding is a little different, it doesn't add to Time but rather assigns each Conc to the nearst Time based on it's Time2:
ind = zeros(size(ab,1),1); %//preallocate memory
for ii = 1:size(ab,1)
[~, ind(ii)] = min(abs(ab(ii,1)-Time)); %//Based on this FEX entry: http://www.mathworks.com/matlabcentral/fileexchange/30029-findnearest-algorithm/content/findNearest.m
end
Time(:,2) = NaN; %// Prefill with NaN
Time(ind, 2) = ab(:,2)
This results in:
Time =
243.00000 NaN
243.00690 NaN
243.01390 NaN
243.02080 NaN
243.02780 0.58140
243.03470 NaN
243.04170 NaN
243.04860 NaN
243.05560 NaN
243.06250 NaN
243.06940 0.64050
243.07640 NaN
243.08330 NaN
243.09030 NaN
243.09720 NaN
243.10420 NaN
243.11110 0.60000
243.11810 NaN
243.12500 NaN
243.13190 NaN
243.13890 NaN
243.14580 NaN
243.15280 0.58480
243.15970 NaN
243.16670 NaN
243.17360 NaN
243.18060 NaN
243.18750 NaN
243.19440 0.58690
for your example inputs

How can I get rid of Nans in Matlab analyzing stock prices?

I have a file with a huge amount of data. Places where there is no information about prices are marked as NaN. I would like to delete all rows, where there are such names and delete all columns where there are a lot of missing data (because I need then proportional matrix).
I also have another string (AssetList) where there is information about all tickers. If column will be deleted, it’s necessary to delete according ticker there.
I would much appreciate any help.
Data:
6,41 16,51 x x 69,78
6,22 16 x x 68,48
6,17 15,61 x x 69,46
x x x x x
x x x x x
x x x x x
5,83 15,14 x x 69,85
6,4 17,64 x x 71,03
6,07 16,04 x x 68,64
5,91 17,09 x x 68,92
6 18,19 x x 68,72
x x x x x
x x x x x
5,58 17,17 x x 69,02
5,3 16,83 x x 67,69
5,66 19,65 x x 68,64
5,65 20,86 x x 69,45
5,43 20,46 x x 68,94
x x x x x
x x x x x
5,58 2 0,16 x 68,73
AssetList:
FLWS SRCE FUBC DDD MMM
I'll have to make some assumptions here, as I didn't fully understand your question.
The following first deletes all rows that exist of NaN exclusively, and continues by deleting all columns that contain at least one NaN:
M = [ ...
6.41 16.51 NaN NaN 69.78
6.22 16 NaN NaN 68.48
6.17 15.61 NaN NaN 69.46
NaN NaN NaN NaN NaN
NaN NaN NaN NaN NaN
NaN NaN NaN NaN NaN
5.83 15.14 NaN NaN 69.85
6.4 17.64 NaN NaN 71.03
6.07 16.04 NaN NaN 68.64
5.91 17.09 NaN NaN 68.92
6 18.19 NaN NaN 68.72
NaN NaN NaN NaN NaN
NaN NaN NaN NaN NaN
5.58 17.17 NaN NaN 69.02
5.3 16.83 NaN NaN 67.69
5.66 19.65 NaN NaN 68.64
5.65 20.86 NaN NaN 69.45
5.43 20.46 NaN NaN 68.94
NaN NaN NaN NaN NaN
NaN NaN NaN NaN NaN
5.58 2 0.16 NaN 68.73];
AssetList = {
'FLWS' 'SRCE' 'FUBC' 'DDD' 'MMM' };
% Delete all-NaN rows
M(all(isnan(M),2),:) = [];
% Delete any-NaN columns
colsToBeDeleted = any(isnan(M));
M(:, colsToBeDeleted) = []
AssetList(colsToBeDeleted) = []
Result:
M =
6.4100 16.5100 69.7800
6.2200 16.0000 68.4800
6.1700 15.6100 69.4600
5.8300 15.1400 69.8500
6.4000 17.6400 71.0300
6.0700 16.0400 68.6400
5.9100 17.0900 68.9200
6.0000 18.1900 68.7200
5.5800 17.1700 69.0200
5.3000 16.8300 67.6900
5.6600 19.6500 68.6400
5.6500 20.8600 69.4500
5.4300 20.4600 68.9400
5.5800 2.0000 68.7300
AssetList =
'FLWS' 'SRCE' 'MMM'