I am wanting to do conditional plotting of vertical lines, that change color based on the value of an integer vector. Those values are integers that range from 0-4.
Currently, I am using a loop to go through the tables to plot the lines. This works, but for LARGE amounts of data it takes time, and I'm wondering if it can be vectorized.
Attached is a stripped down version of the script to loop through a data vector(sample) that simply Loops through the vector, and plots a vertical line based on the value of the integer.
I will also attach the simple variable I created called 'SAMPLE' below to paste into your workspace.
for i=1:size(sample,1)
if sample(i)==1
line( [i i] ,[0 10], 'Marker','.','LineStyle','-','Color','r');
elseif sample(i)==2
line( [i i] ,[0 10], 'Marker','.','LineStyle','-','Color','b');
elseif sample(i)==3
line( [i i] ,[0 10], 'Marker','.','LineStyle','-','Color',[1 .5 0]);
elseif sample(i)==4
line( [i i] ,[0 10], 'Marker','.','LineStyle','-','Color','g');
end
end
Variable:
sample=[[3;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;4;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;2;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;3;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;4;0;0;0;0]];
But is is possible to 'vectorize' plotting in this way w/o having to do it iteratively in a loop as I have done?
Take advantage of the fact that when plotting a line, MATLAB will skip points whose value is NaN.
% Your vector
sample=[3;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;4;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;2;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;3;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;4;0;0;0;0];
% Your colors
colors = [
1 0 0
0 0 1
1 .5 0
0 1 0];
for idx = 1:4
% Find the index of each of your integers
X = find(sample == (idx));
% Force X to be a row vector
X = X(:)';
% Stack two X's on top of one another with a third row filled
% with NaNs. Fill in your Y values in the same way while
% you're at it.
Y = [zeros(size(X)); 10 + zeros(size(X)); nan(size(X))];
X = [X; X; nan(size(X))]; %#ok<AGROW>
% Matlab is column major. By using the colon here, you
% produce a vector that is [X1 X1 nan X2 X2 nan ... etc.]
X = X(:);
Y = Y(:);
% Draw the line
line(X, Y, 'Marker', '.', 'LineStyle', '-', 'Color', colors(idx, :))
end
There's still a loop, but now you're just looping over the possible values instead of looping over the each value in the vector. I think you will find that this will scale much better.
Changing input to:
sample = zeros(1, 1e6);
for idx = 1:4
sample(randi(1e6, 1, 1000)) = idx;
end
and benchmarking with timeit gives a time of 0.0065706 seconds on my machine, while the OP code benchmarks at 1.4861 seconds.
I'd change to something like:
colors=[1 0 0,
0 1 0,
1 0.5 0,
0 0 1];
nnsamples=samples(samples~=0);
for ii=1:size(nnsamples,1)
line( [ii ii] ,[0 10], 'Marker','.','LineStyle','-','Color',colors(nnsamples(ii),:));
end
Related
So essentially I have this code here that I can use to generate a 2D Random Walk discretely along N number of steps with M number of walkers. I can plot them all on the same graph here.
clc;
clearvars;
N = 500; % Length of the x-axis, also known as the length of the random walks.
M = 3; % The amount of random walks.
x_t(1) = 0;
y_t(1) = 0;
for m=1:M
for n = 1:N % Looping all values of N into x_t(n).
A = sign(randn); % Generates either +1/-1 depending on the SIGN of RAND.
x_t(n+1) = x_t(n) + A;
A = sign(randn); % Generates either +1/-1 depending on the SIGN of RAND.
y_t(n+1) = y_t(n) + A;
end
plot(x_t, y_t);
hold on
end
grid on;
% Enlarge figure to full screen.
set(gcf, 'Units', 'Normalized', 'Outerposition', [0, 0.05, 1, 0.95]);
axis square;
Now, I want to be able to Create graphs that show the distribution in space of the positions of a large number
(e.g. n = 1000) random walkers, at three different time points (e.g. t = 100, 200 and 300 or any three time points really).
I'm not sure how to go about this, I need to turn this into a function and iterate it through itself three different times and store the coordinates? I have a rough idea but iffy on actually implementing. I'd assume the safest and least messy way would be to use subplot() to create all three plots together in the same figure.
Appreciate any assistance!
You can use cumsum to linearize the process. Basically you only want to cumsum a random matrix composed of [-1 and 1].
clc;
close all;
M = 50; % The amount of random walks.
steps = [10,200,1000]; % here we analyse the step 10,200 and 1000
cc = hsv(length(steps)); % manage the color of the plot
%generation of each random walk
x = sign(randn(max(steps),M));
y = sign(randn(max(steps),M));
xs = cumsum(x);
xval = xs(steps,:);
ys = cumsum(y);
yval = ys(steps,:);
hold on
for n=1:length(steps)
plot(xval(n,:),yval(n,:),'o','markersize',1,'color',cc(n,:),'MarkerFaceColor',cc(n,:));
end
legend('10','200','1000')
axis square
grid on;
Results:
EDIT:
Thanks to #LuisMendo that answered my question here, you can use a binomial distribution to get the same result:
steps = [10,200,10000];
cc = hsv(length(steps)); % manage the color of the plot
M = 50;
DV = [-1 1];
p = .5; % probability of DV(2)
% Using the #LuisMendo binomial solution:
for ii = 1:length(steps)
SDUDx(ii,:) = (DV(2)-DV(1))*binornd(steps(ii), p, M, 1)+DV(1)*steps(ii);
SDUDy(ii,:) = (DV(2)-DV(1))*binornd(steps(ii), p, M, 1)+DV(1)*steps(ii);
end
hold on
for n=1:length(steps)
plot(SDUDx(n,:),SDUDy(n,:),'o','markersize',1,'color',cc(n,:),'MarkerFaceColor',cc(n,:));
end
legend('10','200','1000')
axis square
grid on;
What is the advantage ? Even if you have a big number of steps, let's say 1000000, matlab can handle it. Because in the first solution you have a bruteforce solution, and in the second case a statistical solution.
If you want to show the distribution of a large number, say 1000, of these points, I would say the most suitable way of plotting is as a 'point cloud' using scatter. Then you create an array of N points for both the x and the y coordinate, and let it compute the coordinate in a loop for i = 1:Nt, where Nt will be 100, 200, or 300 as you describe. Something along the lines of the following:
N = 500;
x_t = zeros(N,1);
y_t = zeros(N,1);
Nt = 100;
for tidx = 1:Nt
x_t = x_t + sign(randn(N,1));
y_t = y_t + sign(randn(N,1));
end
scatter(x_t,y_t,'k*');
This will give you N x and y coordinates generated in the same way as in the sample you provided.
One thing to keep in mind is that sign(0)=0, so I suppose there is a chance (admittedly a small one) of not altering the coordinate. I am not sure if you intended this behaviour to be possible (a walker standing still)?
I will demonstrate the 1-dimensional case for clarity; you only need to implement this for each dimension you add.
Model N steps for M walkers using an NxM matrix.
>> N = 5;
>> M = 4;
>> steps = sign(randn(N,M));
steps =
1 1 1 1
-1 1 -1 1
1 -1 -1 -1
1 1 -1 1
1 -1 -1 -1
For plotting, it is useful to make a second NxM matrix s containing the updated positions after each step, where s(N,M) gives the position of walker M after N steps.
Use cumsum to vectorize instead of looping.
>> s = cumsum(steps)
s =
1 1 1 1
0 2 0 2
1 1 -1 1
2 2 -2 2
3 1 -3 1
To prevent plot redraw after each new line, use hold on.
>> figure; hold on
>> plot(1:N, s(1:N, 1:M), 'marker', '.', 'markersize', 20, 'linewidth', 3)
>> xlabel('Number of steps'); ylabel('Position')
The output plot looks like this: picture
This method scales very well to 2- and 3-dimensional random walks.
Basically the problem I can't solve is how to adapt into a for loop so depending on whatever dimensions I am given it does it on its own. This is an example using 2x2 dimensions. So for example if was to do 3x3 how would I do it in a for loop?
N=4;
R=2;
theta=zeros(1,N);
for k=1:N
theta(k)=2*pi*(k-1)/N;
end
x1=(R*cos(theta+pi/4)/sqrt(2));
y1=(R*sin(theta+pi/4)/sqrt(2));
plot(x1,y1);
fill(x1,y1,'w');
x2=(R*cos(theta+pi/4)/sqrt(2))+R;
y2=(R*sin(theta+pi/4)/sqrt(2));
plot(x2,y2);
fill(x2,y2,'y');
x3=(R*cos(theta+pi/4)/sqrt(2));
y3=(R*sin(theta+pi/4)/sqrt(2))+R;
plot(x3,y3);
fill(x3,y3,'y');
x4=(R*cos(theta+pi/4)/sqrt(2))+R;
y4=(R*sin(theta+pi/4)/sqrt(2))+R;
plot(x4,y4);
fill(x4,y4,'w');
hold;
You could set up a grid of points using ndgrid (or meshgrid).
To create index for the checker pattern, one trick is to use invhilb.
Below I used constant x and y instead of the one you created from R*cos(theta+pi/4)/sqrt(2)
% User input
N = 4;
% Basic square index
x = [0 1 1 0];
y = [0 0 1 1];
% Create axes and set to 'hold'
axes('NextPlot','Add')
% Create grid
[X,Y] = ndgrid(0:N-1);
% Loop over grid
for idx = 1:numel(X)
fh(idx) = fill(X(idx) + x, Y(idx) + y, 'w');
end
% Color as a check board (but with yellow)
set(fh(invhilb(N) > 0),'FaceColor','y')
I have been struggling with this problem for a while and I would appreciate if anyone can help me out. I am able to generate a 10 by 10 matrix and have it randomly assign "1"s in the matrix. My goal is to plot a "star" at the location of each element in the vector that has a value of "1", but I can't seem to figure out how to map the vector to a x-y coordinate system. The code I wrote below generates a plot of 100 stars at each cell and also generates a vector "v", but I don't know how I can link the plot to the vector that instead of having 100 "star"s in my plot, I have however many that there is a value of "1" at the corresponding location of the element.
Thanks!!
David
davidtongg#gmail.com
close all
clear all
clc
a=10;b=10;
v = zeros(a,b);
xy = int32(randi(a, 100, 2));
z = randi(1, 100, 1); % 100 values.
indexes = sub2ind([a, b], xy(:,1), xy(:,2))
v(indexes) = z
m=length(v);
ctr=0;
for i=1:m^2
x_cor(i)=(i-(floor(i/m)*m))*200-100;
y_cor(i)=(floor(i/m)+1)*200-100;
for j=1:m
if i==j*m
x_cor(i)=((i-(floor(i/m)*m))*200-100)+(2*m*100);
y_cor(i)=(floor(i/m))*200-100;
end
end
end
figure(1)
plot(x_cor,y_cor,'*');
grid on
I may of course have misinterpreted this because that code is confusingly complicated, but this is what I think you're after.
For an axb matrix with a random number of ones:
v = randi([0 1], a, b);
Or for a specific number n of ones, in random locations:
v = zeros(a, b);
idx = randi([1 numel(v)], n, 1);
v(idx) = 1; % linear indexing into a matrix
Then to plot them in arbitrarily scaled coordinates:
[y x] = find(v);
x = x * xscale + xoffset;
y = y * yscale + yoffset;
plot(x, y, '*');
Or the really cheaty way:
spy(v);
You can do it easily taking into account that plot(A) , where A is a matrix, plots the columns of the matrix vs their index, and that NaNs are not plotted:
v =[ 1 0 0 0
1 1 0 0
0 0 0 1
1 1 1 1
0 1 1 0 ]; %// example data
v2 = double(v); %// create copy; will be overwritten
v2(~v2) = NaN; %// change zeros to NaNs
plot(bsxfun(#plus, fliplr(v2.'), 0:size(v,1)-1) ,'b*')
%'// transpose and flip from left to right.
%// Add 1 incrementally to each column to have all of them "stacked" in the plot
axis([0 size(v,2)+1 0 size(v,1)+1]) %// set axis limits
set(gca,'xtick',1:size(v,2),'ytick',1:size(v,1)) %// set ticks
grid
Following is my code:
function sierpinski(A, B, C, n)
if n == 0
patch([A(1), B(1), C(1)], [A(2), B(2), C(2)], [0.0 0.0 0.0]);
else
sierpinski(A, (A + B)/2, (A + C)/2, n-1);
sierpinski(B, (B + A)/2, (B + C)/2, n-1);
sierpinski(C, (C + A)/2, (C + B)/2, n-1);
end
% sierpinski([0 0], [1 0], [.5 .8], 8)
It's not very effectly. I want to first generating all data then patched, but I don't know how to correctly used. Also, can my code be written use for loops?
Your idea to write one function to generate the data and another to plot it is a good one - it's often a good idea to separate data generation from processing, and processing from output. I would do it something like this:
function out = sierpinski(a, b, c, n)
if n == 0
out.xvals = [a(1), b(1), c(1)];
out.yvals = [a(2), b(2), c(2)];
else
out1 = sierpinski(a, (a+b)/2, (a+c)/2, n-1);
out2 = sierpinski(b, (a+b)/2, (b+c)/2, n-1);
out3 = sierpinski(c, (a+c)/2, (b+c)/2, n-1);
out = [out1, out2, out3];
end
end
This creates a struct of length 3^n, each entry of which contains the coordinates of one of the small triangles in the sierpinski triangle. Your code to plot it might then look like
>> out = sierpinski([0,0], [1,0], [0.5, sqrt(3)/2], 8);
>> figure(); hold on;
>> for i = 1:length(out)
patch(out(i).xvals, out(i).yvals, 'k');
end
That crashes on my machine (it seems that Matlab doesn't handle thousands of patches on the same plot very well) but a similar loop which plots one point at the corner of each small triangle.
>> x = [out.xvals];
>> y = [out.yvals];
>> plot(x, y, '.');
which produces this plot
I don't have any code-examples ready, but:
Instead of drawing each triangle as a single patch-object, you could try drawing all triangles in one large patch.
Basically you'd only need to concatenate the x- and y-coordinates for each triangle separated by a NaN - this will prevent the patch from drawing lines connecting individual triangles.
E.g. the following line produces two separate triangles:
p = patch( [0 0.5 1 0 NaN 2 2.5 3 2 NaN ], [ 0 1 0 0 NaN 2 3 2 2 NaN], 'k')
Mind that, to have a closed triangle you need 4 points per triangle this way, the last point being identical to the first.
EDIT:
For each recursion level, you can 'erase' the central triangles, so you have to patch many fewer triangles. For example, at first level, you have three 'up' triangles and only one 'down' triangle. You can path this, instead of the other three.
a more compact routine is:
function sierpinski(rec)
[x, x0] = deal(cat(3, [1 0]', [-1 0]', [0 sqrt(3)]'));
for k = 1 : rec x = x(:,:) + x0 * 2 ^ k / 2;
end
patch('Faces', reshape(1 : 3 * 3 ^ k, 3, '')', 'Vertices', x(:,:)')
end
So you have to fill much less triangles if...
function sierpinski(rec)
close all
%Main Triangle
hFig=figure;
units=get(hFig,'units');
set(hFig,'units','normalized','outerposition',[0 0 1 1], 'Color', 'white');
set(hFig,'units',units); clear units
hold on
Vx=[0 0.5 1]; Vy=[0 realsqrt(3)/2 0];
fill(Vx,Vy,'b')
%the number of white triangles = sum(3.^(0:1:rec-1))
whitex=NaN(3,sum(3.^(0:1:rec-1))); whitey=whitex; K=1;
for S=1:rec
[Vx,Vy]=sierpinskisect;
end
fill(whitex,whitey,'w')
function [outX,outY]=sierpinskisect
%the number of blue triangles = 3^S
L=size(Vx,1);
outX=NaN(3*L,3); outY=outX; J=1;
for I=1:L
%left blue triangle
outX(J,:)=[Vx(I,1) mean(Vx(I,(1:2))) mean(Vx(I,([1 3])))];
outY(J,:)=[Vy(I,1) mean(Vy(I,(1:2))) mean(Vy(I,([1 3])))];
J=J+1;
%right blue triangle
outX(J,:)=[mean(Vx(I,([1 3]))) mean(Vx(I,(2:3))) Vx(I,3)];
outY(J,:)=[mean(Vy(I,([1 3]))) mean(Vy(I,(2:3))) Vy(I,3)];
J=J+1;
%upper blue triangle
outX(J,:)=[mean(Vx(I,(1:2))) Vx(I,2) mean(Vx(I,(2:3)))];
outY(J,:)=[mean(Vy(I,(1:2))) Vy(I,2) mean(Vy(I,(2:3)))];
J=J+1;
%white triangle
whitex(:,K)=[outX(J-3,2);outX(J-3,3);outX(J-2,2)];
whitey(:,K)=[outY(J-3,2);outY(J-3,3);outY(J-2,2)];
K=K+1;
end
end
end
Hi I would like to plot transparent cube-shaped grid with lines in it. Something like this:
However, I managed only to draw a 2D grid:
[X,Y] = meshgrid(-8:.5:8);
Z = X+1;
surf(X,Y,Z)
I use Matlab R2009b.
If it is impossible to plot this in matlab could you recommend me a software I could use.
Consider this vectorized solution. It has the advantage that it creates a single graphic object:
%# these don't all have to be the same
x = -8:2:8; y = -8:2:8; z = -8:2:8;
[X1 Y1 Z1] = meshgrid(x([1 end]),y,z);
X1 = permute(X1,[2 1 3]); Y1 = permute(Y1,[2 1 3]); Z1 = permute(Z1,[2 1 3]);
X1(end+1,:,:) = NaN; Y1(end+1,:,:) = NaN; Z1(end+1,:,:) = NaN;
[X2 Y2 Z2] = meshgrid(x,y([1 end]),z);
X2(end+1,:,:) = NaN; Y2(end+1,:,:) = NaN; Z2(end+1,:,:) = NaN;
[X3 Y3 Z3] = meshgrid(x,y,z([1 end]));
X3 = permute(X3,[3 1 2]); Y3 = permute(Y3,[3 1 2]); Z3 = permute(Z3,[3 1 2]);
X3(end+1,:,:) = NaN; Y3(end+1,:,:) = NaN; Z3(end+1,:,:) = NaN;
%#figure('Renderer','opengl')
h = line([X1(:);X2(:);X3(:)], [Y1(:);Y2(:);Y3(:)], [Z1(:);Z2(:);Z3(:)]);
set(h, 'Color',[0.5 0.5 1], 'LineWidth',1, 'LineStyle','-')
%#set(gca, 'Box','on', 'LineWidth',2, 'XTick',x, 'YTick',y, 'ZTick',z, ...
%# 'XLim',[x(1) x(end)], 'YLim',[y(1) y(end)], 'ZLim',[z(1) z(end)])
%#xlabel x, ylabel y, zlabel z
axis off
view(3), axis vis3d
camproj perspective, rotate3d on
If you don't mind a few for loops, something like this will work:
clf
figure(1)
for g = 0:.2:2
for i = 0:.2:2
plot3([g g], [0 2], [i, i])
hold on
end
end
for g = 0:.2:2
for i = 0:.2:2
plot3([0 2], [g g], [i, i])
hold on
end
end
for g = 0:.2:2
for i = 0:.2:2
plot3([i i], [g g], [0 2])
hold on
end
end
You will just need to make the grid transparent by probably changing line properties, I don't think you can change alpha values to accomplish this. Hope that is helpful.
A more vectorized version of Stephen's answer might be the following:
i = 0:0.2:2;
[X Y] = meshgrid(i,i);
x = [X(:) X(:)]';
y = [Y(:) Y(:)]';
z = [repmat(i(1),1,length(x)); repmat(i(end),1,length(x))];
col = 'b';
hold on;
plot3(x,y,z,col);
plot3(y,z,x,col);
plot3(z,x,y,col);
Unfortunately, MATLAB does not currently support transparent lines (to my knowledge). If you really need them to be transparent I'd suggest using 'patch'.
I understand this is a late reply but it is still valid in case anyone else is looking at doing the same thing.
Assuming you are plotting cubes (/their edges), an alternative to the answers already provided is to use the 'plotcube' code from Oliver:
plotcube
The advantage of this solution is that you can:
Change the transparency of the faces (FaceAlpha), and/or,
Change the transparency of the edges (EdgeAlpha), and/or,
Change the colour of the lines (EdgeColor).
All of these can be constants, or variables.
(e.g. fixed edge colour, or a colour that changes with Z-value etc.)
To add in functionality of 2. and 3. (above) change the 'cellfun(#patch...' section in Olivers code, adding in the four extra lines of code as follows: (replace the whole cellfun section with this; including the new 'EdgeAlpha' and 'EdgeColor' lines):
cellfun(#patch,XYZ{1},XYZ{2},XYZ{3},...
repmat({clr},6,1),...
repmat({'FaceAlpha'},6,1),...
repmat({alpha},6,1),...
repmat({'EdgeAlpha'},6,1),...
repmat({0.2},6,1),... % Set this value to whatever you want; even a variable / matrix
repmat({'EdgeColor'},6,1),...
repmat({'black'},6,1)...
);
For more info on 'patch' please see patch documentation.
An important note:
- for large models (many cubes) this is very slow to run.
e.g. running this 'plotcube' function in a 'for' loop in MATLAB over thousands of blocks. I believe this is from calling the 'patch' function multiple times.
A better solution would be to vectorise; to put all your points (vertices/faces/whatever) together in a single matrix first and then call the #patch function only once (no 'for' loop). This would require changing the code somehow to update all the XYZ data.
I hope that helps someone.
Here is the 'plotcube' code in case the link to the original code by Oliver breaks someday:
function plotcube(varargin)
% PLOTCUBE - Display a 3D-cube in the current axes
%
% PLOTCUBE(EDGES,ORIGIN,ALPHA,COLOR) displays a 3D-cube in the current axes
% with the following properties:
% * EDGES : 3-elements vector that defines the length of cube edges
% * ORIGIN: 3-elements vector that defines the start point of the cube
% * ALPHA : scalar that defines the transparency of the cube faces (from 0
% to 1)
% * COLOR : 3-elements vector that defines the faces color of the cube
%
% Example:
% >> plotcube([5 5 5],[ 2 2 2],.8,[1 0 0]);
% >> plotcube([5 5 5],[10 10 10],.8,[0 1 0]);
% >> plotcube([5 5 5],[20 20 20],.8,[0 0 1]);
% Default input arguments
inArgs = { ...
[10 56 100] , ... % Default edge sizes (x,y and z)
[10 10 10] , ... % Default coordinates of the origin point of the cube
.7 , ... % Default alpha value for the cube's faces
[1 0 0] ... % Default Color for the cube
};
% Replace default input arguments by input values
inArgs(1:nargin) = varargin;
% Create all variables
[edges,origin,alpha,clr] = deal(inArgs{:});
XYZ = { ...
[0 0 0 0] [0 0 1 1] [0 1 1 0] ; ...
[1 1 1 1] [0 0 1 1] [0 1 1 0] ; ...
[0 1 1 0] [0 0 0 0] [0 0 1 1] ; ...
[0 1 1 0] [1 1 1 1] [0 0 1 1] ; ...
[0 1 1 0] [0 0 1 1] [0 0 0 0] ; ...
[0 1 1 0] [0 0 1 1] [1 1 1 1] ...
};
XYZ = mat2cell(...
cellfun( #(x,y,z) x*y+z , ...
XYZ , ...
repmat(mat2cell(edges,1,[1 1 1]),6,1) , ...
repmat(mat2cell(origin,1,[1 1 1]),6,1) , ...
'UniformOutput',false), ...
6,[1 1 1]);
cellfun(#patch,XYZ{1},XYZ{2},XYZ{3},...
repmat({clr},6,1),...
repmat({'FaceAlpha'},6,1),...
repmat({alpha},6,1)...
);
view(3);
you can make the inside line kind of transparent by setting color = [0.65, 0.65, 0.65]. And you can use dash line style for interior lines and solid lines for boundary to make it more like a 3-D object.
In my software package, I code a mesh3 function to plot the 3-D tensor product meshes.
clear all
close all
clc
Nx=11;
Ny=11;
Nz=11;
clf
hold on
[i,j]=meshgrid(1:Nx,1:Ny);
k=zeros(Ny,Nx)+Nz;
surf(i,j,k)
[i,k]=meshgrid(1:Nx,1:Nz);
j=zeros(Nz,Nx)+Ny;
surf(i,j,k)
[j,k]=meshgrid(1:Ny,1:Nz);
i=zeros(Nz,Ny)+Nx;
surf(i,j,k)
[i,j]=meshgrid(1:Nx,1:Ny);
k=zeros(Ny,Nx)+1;
surf(i,j,k)
[i,k]=meshgrid(1:Nx,1:Nz);
j=zeros(Nz,Nx)+1;
surf(i,j,k)
[j,k]=meshgrid(1:Ny,1:Nz);
i=zeros(Nz,Ny)+1;
surf(i,j,k)
view(30,30)