How to change size of grid & granularity in meshc function - matlab

Show mask by meshc function
z = [0 0 0 0;0 1 1 0;0 0 0 0];
meshc(z)
Output is:
Desired output:

There is a lot of guessing on my side, and I guess you want something like this:
%// data
z = [0 0 0 0;0 1 1 0;0 0 0 0];
%// grid
[n,m] = size(z);
[x,y] = ndgrid(1:n,1:m);
%// finer grid
[xq, yq] = ndgrid(linspace(1,n,100),linspace(1,m,100));
%// interpolation
F = griddedInterpolant(x, y, z, 'cubic')
zq = F(xq, yq);
%// interpolated plot
figure(1)
meshc(xq,yq,zq)

Related

MATLAB - Update Plot with Matrix

I want to plot data, which is stored in an array. A contains three columns, each column represents a different data set. The following code works fine:
A = [0 0 0;
0 1 0];
h = plot(A)
However, a new line is appended to A and the plot shall be updated. I read that you can update plots with set and 'XData':
A = [0 0 0;
0 1 0;
1 2 0];
set(h,'XData',A)
This throws me an error: Error using set.
Value must be a column or row vector. Is there any way to refresh the data instead of a new plot? The following works just fine?
A = [0 0 0;
0 1 0;
1 2 0];
h = plot(A)
The initial code
A = [0 0 0;
0 1 0];
h = plot(A)
generates three line objects, one for each column of A (check that h has size 3×1). So you need to update each of those lines in a loop. Also, you need to update both the 'XData' and 'YData' properties:
for k = 1:numel(h)
set(h(k), 'XData', 1:size(A,1), 'YData', A(:,k))
end
You could use linkdata (https://mathworks.com/help/matlab/ref/linkdata.html):
A = [
0 0 0;
0 1 0
];
plot(A);
linkdata on;
A = [
0 0 0;
0 1 0;
1 2 0
];
Another approach deleting the plot and redrawing it immediately after:
h = plot(x,y);
% modify data...
delete(h);
h = plot(x,y);

matlab - line equation to 2D matrix with values of 1 and 0

As the title says, I want to covert a line(or any equation) to 2D matrix.
For example: If I have a line equation y = x, then I want it to be like:
0 0 0 0 0 1
0 0 0 0 1 0
0 0 0 1 0 0
0 0 1 0 0 0
0 1 0 0 0 0
1 0 0 0 0 0
and the length of rows and columns can be variable.
Is there a function or method to implement that?
use meshgrid to get x-y grids:
% set resolution parameters
xmin = 1;
xmax = 100;
dx = 0.1;
ymin = 1;
ymax = 100;
dy = 0.1;
% set x-y grid
[xg, yg] = meshgrid(xmin:dx:xmax, ymin:dy:ymax);
% define your function
f = #(x) (x - 30).^2;
% apply it on the x grid and get close y values
D = abs(f(xg) - yg);
bw = D <= 1;
figure;
imshow(bw);
% flip y axis
set(gca,'YDir','normal')
you get:
and then you can further dilate/erode/skeletonize the output
Given x and y coordinates, how to fill in a matrix with those coordinates? As it is said, just do it in a for loop, or use the "sub2ind" function.
% x,y coordinates
x=0:.01:30;
y=10*sin(2*pi*.1*x);
% add offset so that (x,y)-coordinates are always positive
x=x+abs(min(x))+1;
y=y+abs(min(y))+1;
figure,plot(x,y,'.');axis tight
x=ceil(x); y=ceil(y);
im=zeros(max(y),max(x));
ind=sub2ind(size(im),y,x);
im(ind)=1;
figure,imagesc(im),axis image, axis xy;colormap gray;axis tight
xlabel('x'); ylabel('y')
Why not doing it on your own? You loop through all x-coordinates of the matrix that you (probably scaled) use as the x for your function and get an y out, that you (probably scaled) can round and then use as a y coordinate for your matrix to set the 1.

How can I display a Biograph object in a subplot?

I want to plot some biographs in some subplots. Please help me to do this task.
There is my code:
cm = [0 1 1 0 0;1 0 0 1 1;1 0 0 0 0;0 0 0 0 1;1 0 1 0 0];
cm2 = [0 1 1 0 1;1 0 1 1 1;1 0 0 0 0;0 0 0 0 1;1 0 1 1 0];
figure(18);
subplot(2,1,1);
view(biograph(cm));
subplot(2,1,2);
view(biograph(cm2));
Here's a modification of #SardarUsama's answer that should be suitable for newer MATLAB versions (where gcf no longer returns a handle to the biograph figure):
function hF = q41124642()
cm = [0 1 1 0 0; 1 0 0 1 1; 1 0 0 0 0; 0 0 0 0 1; 1 0 1 0 0];
cm2 = [0 1 1 0 1; 1 0 1 1 1; 1 0 0 0 0; 0 0 0 0 1; 1 0 1 1 0];
% Look for biograph figures before and after ploting to know which figures to use
hBG{1} = findall( 0, 'Tag', 'BioGraphTool' ); % Before
view( biograph(cm) );
view( biograph(cm2) );
hBG{2} = findall( 0, 'Tag', 'BioGraphTool' ); % After
hBG = setdiff( hBG{2}, hBG{1} ); % (The difference contains the new figures)
% Create a new figure to hold the subplots:
hF = figure();
% Create and get handles of subplot axes:
s(1) = subplot(1,2,1);
s(2) = subplot(1,2,2);
% Retrieve children and copy to new parents, hiding the axes
IS_CHILD_AX = arrayfun( #(x)isa( x, 'matlab.graphics.axis.Axes' ), hBG(1).Children );
copyobj( hBG(1).Children(IS_CHILD_AX).Children, s(1) );
copyobj( hBG(2).Children(IS_CHILD_AX).Children, s(2) );
axis( s, 'off' );
% Close the biograph figures:
close(hBG);
Notes:
Tested on R2018a.
I knew I should look for 'Tag','BioGraphTool' by following biograph.view into biograph.bggui until I found some identifying features of the created figure. Had this been unavailable, we'd simply ask findall for a list of figures, twice, applying the same diff logic.
Code:
h(1) = figure;
view(biograph(cm));
fig(1)=gcf; ax1=gca; % Figure and axes handles
c1 = get(fig(1), 'Children');
copyobj(c1,h(1)); % Copying the object to h(1)
h(2) = figure;
view(biograph(cm2));
fig(2)=gcf; ax2=gca; % Figure and axes handles
c2 = get(fig(2), 'Children');
copyobj(c2,h(2)); % Copying the object to h(2)
figure;
% Creating and getting handles of subplot axes
% Retrieving properties of children and copying to new parents and hiding the axes lines
s1 = subplot(1,2,1); bg1 = get(ax1,'children'); copyobj(bg1,s1); axis off;
s2 = subplot(1,2,2); bg2 = get(ax2,'children'); copyobj(bg2,s2); axis off;
close(fig); close(h); % Closing previously opened figures
Output:

How do I create a plot like this grid in MATLAB?

I have data like this
-1 -1 -1 1 0 0 1 1 -1 0 1 -1 0 1
where each element of the vector is one of a several states. In this case (which is arbitrary and obviously only an example), are -1 0 1. I'm trying to make a plot like this grid:
The closest I was able to get was with a combination of spy and various tweaks:
%% ARBITRARY example data
states = [-1 0 1];
data = [-1 -1 -1 1 0 0 1 1 -1 0 1 -1 0 1];
%% Approximate plot using sparse matrix and spy
T = size(data, 2);
num_states = size(states, 2);
g = zeros(num_states, T);
for idx = 1:T
jdx = find(data(idx) == states, 1, 'first');
g(jdx, idx) = 1;
end
g = sparse(g);
%% Tweak plot
obj = figure();
obj.Color = 'white';
spy(g, 30)
s = obj.Children(1);
s.XLim = [1 T];
s.YLim = [1 num_states];
s.XLabel.String = '';
s.XGrid = 'on';
s.YTick = 1:num_states;
s.YTickLabel = num2cell(states);
s.GridLineStyle = '-';
s.YGrid = 'on';
However, this is far from ideal, since a) it's not actually a shaded grid, and b) the ticks on the y-axis are in descending order, starting from the bottom, because this is how spy functions, among other problems. How do I make a plot like this? I'm using MATLAB 2015b on a Windows 7 64-bit machine.
You'll want to play around with colours and grids, but this should be sufficient to get started:
data = [-1 -1 -1 1 0 0 1 1 -1 0 1 -1 0 1];
states = flipud(unique(data)');
im = bsxfun(#eq,data,states);
image(im);
colormap([1 1 1;0 0 0]);
axis equal;
axis tight;
set(gca,'XTick',1:length(data));
grid minor
set(gca,'YTickLabel',states);
The above results in

Contour colors don't correspond to color bar when a surf plot is added

Below is some code that recreates my problem as simplified as I can make it. It does a subplot with two plots, you'll notice the plot on the right (contour only) has the correct correlation between the contour colors and the color bar but when a surface is added (left plot) the colors no longer match up.
Notes:
I've tried contourslice but I get the same results. I've posted the code for that below too.
How far off the colors are seems to depend on the values of the contour data itself. If you replace my contour data with peaks, it works fine. However this does not solve the underlying problem.
Code using contour:
clear all; close all; clc
%define box coordinates
bx = [0 1 1 0 0;0 1 1 0 0]-.5;
by = [0 0 1 1 0;0 0 1 1 0]-.5;
bz = [0 0 0 0 0;1 1 1 1 1]-.5;
%make contour data
[x,y] = meshgrid(-1:.5:1,-1:.5:1);
con = (x.^2+y.^2);
figure(1)
subplot(1,2,1)
box = surf(bx,by,bz); %draw box
set(box,'FaceColor',[1 1 1],'FaceAlpha',1,'EdgeAlpha',0,'EdgeColor',[.5 .5 .5])
hold on
camlight(30,70)
contour(x,y,con) %draw contour
colorbar
axis([-1 1 -1 1 -1 1])
axis equal
subplot(1,2,2)
contour(x,y,con)
axis([-1 1 -1 1])
axis equal
colorbar
set(gcf,'outerposition',[150 150 800 300])
Code using contourslice instead of contour (same problem)
clear all; close all; clc
%define box coordinates
bx = [0 1 1 0 0;0 1 1 0 0]-.5;
by = [0 0 1 1 0;0 0 1 1 0]-.5;
bz = [0 0 0 0 0;1 1 1 1 1]-.5;
x = -1:.5:1;
y = x;
z = x;
%make contour data
[xg,yg,zg] = ndgrid(x,y,z);
V = 3-(xg.^2+yg.^2+zg.^2);
figure(1)
subplot(1,2,1)
box = surf(bx,by,bz); %draw box
set(box,'FaceColor',[1 1 1],'FaceAlpha',1,'EdgeAlpha',0,'EdgeColor',[.5 .5 .5])
hold on
camlight(30,70)
contourslice(x,y,z,V,[],[],0) %draw contour
colorbar
axis([-1 1 -1 1 -1 1])
axis equal
subplot(1,2,2)
contour(x,y,V(:,:,3))
axis([-1 1 -1 1])
axis equal
colorbar
set(gcf,'outerposition',[150 150 800 300])
Thanks for your help!
Just set the caxis property as you wish:
colorbar
caxis([0 2])
...
colorbar
caxis([0 2])
The problem was probably caused, because the surf plot changed the color determining values of your plot. By setting a fixed color axis you can avoid all misinterpretations.