Matlab - Attempt to reference field of non-structure array - arrays

I'm working in a project related with vegetation detection and i'm following this tutorial of Matlab to calculate NDVI.
Finding Vegetation in a Multispectral Image
But I'm having an error that i don't know why its happening.
this is the code:
% Create a figure with a 1-by-2 aspect ratio
h = figure;
p = h.Position;
h.Position = [p(1,1:3),p(3)/2];
subplot(1,2,1)
% Create the scatter plot
plot(red, NIR, '+b')
hold on
plot(red(q(:)), NIR(q(:)), 'g+')
ax = gca;
ax.XLim = [0 1];
ax.YLim = [0 1];
axis square
xlabel('red level')
ylabel('NIR level')
title('NIR vs. Red Scatter Plot')
% Display the thresholded NDVI
subplot(1,2,2)
imshow(q)
h.Colormap = [0 0 1; 0 1 0];
title('NDVI with Threshold Applied')
And this is the error:
??? Attempt to reference field of non-structure array.
Error in ==> teste_nir at 51
p = h.Position;
Can anybody help me?

Depending on what version of Matlab you are using, you may need to use the following instead:
p = get(h,'Position');

Related

Interactive plot to change array values (MATLAB)

N = 500;
pattern = zeros(N,N);
grid on
plot(pattern)
% gets coordinates of modified cells
[x,y] = ginput;
% convert coordinates to integers
X = uint8(x);
Y = uint8(y);
% convert (X,Y) into linear indices
indx = sub2ind([N,N],x,y);
% switch desired cells on (value of 1)
pattern(indx) = 1;
I'm trying to assign several elements of a zeros array the value of 1. Basically I want to create an interactive plot where the user decides what cells he wants to turn on and then save his drawing as a matrix. In Python it's very simple to use the on_click with Matplotlib, but Matlab is weird and I can't find a clear answer. What's annoying is you can't see where you clicked until you save your changes and check the final matrix. You also can't erase a point if you made a mistake.
Moreover I get the following error : Error using sub2ind Out of range subscript. Error in createPattern (line 12) indx = sub2ind([N,N],X,Y);
Any idea how to fix it?
function CreatePattern
hFigure = figure;
hAxes = axes;
axis equal;
axis off;
hold on;
N = 3; % for line width
M = 20; % board size
squareEdgeSize = 5;
% create the board of patch objects
hPatchObjects = zeros(M,M);
for j = M:-1:1
for k = 1:M
hPatchObjects(M - j+ 1, k) = rectangle('Position', [k*squareEdgeSize,j*squareEdgeSize,squareEdgeSize,squareEdgeSize], 'FaceColor', [0 0 0],...
'EdgeColor', 'w', 'LineWidth', N, 'HitTest', 'on', 'ButtonDownFcn', {#OnPatchPressedCallback, M - j+ 1, k});
end
end
Board = zeros(M,M);
playerColours = [1 1 1; 0 0 0];
xlim([squareEdgeSize M*squareEdgeSize]);
ylim([squareEdgeSize M*squareEdgeSize]);
function OnPatchPressedCallback(hObject, eventdata, rowIndex, colIndex)
% change FaceColor to player colour
value = Board(rowIndex,colIndex);
if value == 1
set(hObject, 'FaceColor', playerColours(2, :));
Board(rowIndex,colIndex) = 0; % update board
else
set(hObject, 'FaceColor', playerColours(1, :));
Board(rowIndex,colIndex) = 1; % update board
end
end
end
I found this link and modified the code to be able to expand the board and also select cells that have been turned on already to switch them off.
Now I need a way to extract that board value to save the array.

How do I fix fix error in plotting due to indexing?

import numpy as np
from pcw import dls
n = 5
alpha = np.logspace(-1, -5, n)
x = 0.5/alpha
uw = np.logspace(-9, 1)
t = 0.25/uw
for i in range(len(x)):
s = 2*np.array(dls([x[i]],t)) ###may be error is here due to index or something
print(s)
fontsize_labels = 12
fontsize_tick_labels = 12
fontsize_legend = 10
fig = plt.figure()
ax1 = fig.add_subplot(111)
color_list = plt.rcParams['axes.prop_cycle'].by_key()['color']
ax1.loglog(uw, s, linewidth=2, color=color_list[1], clip_on=True)
ax1.set_xlabel(r'$u_{w}$', fontsize=fontsize_labels)
ax1.set_ylabel(r'$s_{w}\ /\ (Q/4 \pi T)$', fontsize=fontsize_labels)
ax1.tick_params(axis='both', which='major', labelsize=fontsize_tick_labels)
ax1.yaxis.set_ticks_position('both')
ax1.xaxis.set_ticks_position('both')
ax1.set_ylim(1e-4, 1e2)
ax1.set_xlim(1e-9, 1e1)
ax1.legend(frameon=False, loc='best', fontsize=fontsize_legend)
# plt.tight_layout()
plt.show()
Hi All,
I am a very beginner in Python. After running this code, I am expecting to get five curves in a single plot but I am getting five different plots. Please suggest to me how to get over this error. The error may be near for loop as per my knowledge. Your help will be highly appreciated.
#Diziet Asahi I want all five curves on the same axes.
You need to take the figure and axes creation outside of your loop:
fig = plt.figure()
ax1 = fig.add_subplot(111)
for i in range(len(x)):
(...)
ax1.loglog(uw, s, linewidth=2, color=color_list[1], clip_on=True)
(...)
plt.show()

How to find the index of a cell (vector case) in Matlab

I just search the following related discussions:
How do I find a specific cell within a cell array?.
https://www.mathworks.com/matlabcentral/answers/84242-find-in-a-cell-array
However, they are not what I want exactly.
v = [1 0]; u = [0 1];
C = {v, u; u, u+u}
I create a cell C above with each element a row vector.
If I do
C{2,2}
it shows
ans =
0 2
Inversely, if I know [0 2], I want to find where it is, i.e., I want to get {2,2}, how could I do?
For the scalar case, the answer is shown in the second link; however, I cannot find the answer for the vector case so far.
Thanks!
Following this answer you linked to you can do :
found = cellfun(#(c) isequal(c,[0 2]),c)
which outputs
found =
2×2 logical array
0 0
0 1
lastly to get the coordinates you would use find :
[row,col] = find(found==1)
The output will be
row = 2
col = 2

Change diagonals of an array of matrices

I have an application with an array of matrices. I have to manipulate the diagonals several times. The other elements are unchanged. I want to do things like:
for j=1:nj
for i=1:n
g(i,i,j) = gd(i,j)
end
end
I have seen how to do this with a single matrix using logical(eye(n)) as a single index, but this does not work with an array of matrices. Surely there is a way around this problem. Thanks
Use a linear index as follows:
g = rand(3,3,2); % example data
gd = [1 4; 2 5; 3 6]; % example data. Each column will go to a diagonal
s = size(g); % size of g
ind = bsxfun(#plus, 1:s(1)+1:s(1)*s(2), (0:s(3)-1).'*s(1)*s(2)); % linear index
g(ind) = gd.'; % write values
Result:
>> g
g(:,:,1) =
1.000000000000000 0.483437118939645 0.814179952862505
0.154841697368116 2.000000000000000 0.989922194103104
0.195709075365218 0.356349047562417 3.000000000000000
g(:,:,2) =
4.000000000000000 0.585604389346560 0.279862618046844
0.802492555607293 5.000000000000000 0.610960767605581
0.272602365429990 0.551583664885735 6.000000000000000
Based on Luis Mendo's answer, a version that may perhaps be more easy to modify depending on one's specific purposes. No doubt his version will be more computationally efficient though.
g = rand(3,3,2); % example data
gd = [1 4; 2 5; 3 6]; % example data. Each column will go to a diagonal
sz = size(g); % Get size of data
sub = find(eye(sz(1))); % Find indices for 2d matrix
% Add number depending on location in third dimension.
sub = repmat(sub,sz(3),1); %
dim3 = repmat(0:sz(1)^2:prod(sz)-1, sz(1),1);
idx = sub + dim3(:);
% Replace elements.
g(idx) = gd;
Are we already playing code golf yet? Another slightly smaller and more readable solution
g = rand(3,3,2);
gd = [1 4; 2 5; 3 6];
s = size(g);
g(find(repmat(eye(s(1)),1,1,s(3))))=gd(:)
g =
ans(:,:,1) =
1.00000 0.35565 0.69742
0.85690 2.00000 0.71275
0.87536 0.13130 3.00000
ans(:,:,2) =
4.00000 0.63031 0.32666
0.33063 5.00000 0.28597
0.80829 0.52401 6.00000

Return matrices of row and column indices

I am sure this question must be answered somewhere else but I can't seem to find the answer.
Given a matrix M, what is the most efficient/succinct way to return two matrices respectively containing the row and column indices of the elements of M.
E.g.
M = [1 5 ; NaN 2]
and I want
MRow = [1 1; 2 2]
MCol = [1 2; 1 2]
One way would be to do
[MRow, MCol] = find(ones(size(M)))
MRow = reshape(MRow, size(M))
MCol = reshape(MCol, size(M))
But this does not seem particular succinct nor efficient.
This essentially amounts to building a regular grid over possible values of row and column indices. It can be achieved using meshgrid, which is more effective than using find as it avoids building the matrix of ones and trying to "find" a result that is essentially already known.
M = [1 5 ; NaN 2];
[nRows, nCols] = size(M);
[MCol, MRow] = meshgrid(1:nCols, 1:nRows);
Use meshgrid:
[mcol, mrow] = meshgrid(1:size(M,2),1:size(M,1))

Resources