Plotting interactive lattice in a simulation matlab - matlab

I'm running a simulation that describes activity at the front and back of a 2D, square lattice. the front and back are described for example by:
front= [-1 1 -1 0 1 0 1 2 -2 1 ];
back = [ 1 0 0 0 2 0 1 -2 -2 1 ];
each number indicates different activity on the lattice.
I want to plot this interactively so that each value in the lattice will be marked by a different marker and color and the plot will be updated every iteration.
So far I have something like:
% the upper and lower edges of the lattice
figure (1)
hold on
plot(linspace(1,100,10),10*ones(1,10),'k'); %front
plot(linspace(1,100,10),1*ones(1,10),'k'); %back
% the front and back when are equal 0 zero (initial condition)
plot(100*ones(1,10),1:10,'ob','markersize',10); % front
plot(1*ones(1,10),1:10,'ob','markersize',10); % back
xlim([-1 101])
ylim([-1 11])
This marks the initial setup of the system I'm working on, plot it to see what I'm referring to.
now in each iteration I want to view the circles change colors for different values, for example:
figure (1)
ind=find(front==1);
if (isenum(ind)==0)
plot(100*ones(1,length(ind)),ind,'or','markerfacecolor','r');
end
This is done 10 times, for 5 values at the front and 5 at the back, and is quite heavy on the simulation
I wish to find a way that I can span the entire vector front/back on the lattice with "one go" and have different markers assigned to each value. I manage to do it with imagesc, however, I lose the graphics I want to keep while piloting the markers (I wish to add arrows and other stuff later as well). does anyone have any experience with these kind of things?

Related

Limitation to MATLAB Hidden Line Removal?

I've asked this question on Mathwork's site so if cross-posting isn't allowed let me know and I'll delete this.
I'm trying to render small objects and large objects together in MATLAB. I'm using the camera commands to restrict my field of view such that I can see both. However, when I do that, the hidden line removal fails on the small objects. I would have thought that hidden line removal would have been done at machine precision for floats, but it appears not. Is this a function of my graphics card or can I work around this?
The code below is the minimum example I could come up with. Plotted on an axis with default limits, the hidden line removal works fine (left) When the axis is set to large extents (compared to the object) the line removal fails (middle). When I make the axis disappear things are fine again (right).
For this example, I can just hide the axis and the output looks correct. But for what I'm actually trying to do, that's not an option. Any suggestions or can someone point me to the proper limit between the smallest and largest objects in a scene that will properly render?
The code to generate the spheres above is below. Thanks in advance!
Images as generated by MATLAB 2018A
clearvars
F1 = figure(1);
clf
set(F1,'color',[1 1 1],'Renderer','opengl'); % have to enable this to clip surfaces behind the camera
for step = [2 1 3] % out of order because the axis in case 2 is trying to hide the first plot
subplot(1,3,step)
view(gca,3);
camproj(gca,'Perspective'); % have to enable this to clip surfaces behind the camera
[Xs,Ys,Zs] = sphere(20);
r = 30e-6;
surf(gca,Xs*r,Ys*r,Zs*r);
axis(gca,'equal');
% three different behaviors, pick a number 1, 2, or 3
switch step
case 1 % this plots the sphere correctly
%axis([-2 2 -2 2 -2 2]);
%axis off
case 2 % this messes up the hidden line removal
axis([-2 2 -2 2 -2 2]);
%axis off
case 3 % removing the axis walls fixes things again
axis([-2 2 -2 2 -2 2]);
axis off
end
% put viewpoint on unit sphere
camera_pos = get(gca,'CameraPosition');
mag_camera_pos = sqrt(sum(camera_pos.^2));
camera_pos = camera_pos / mag_camera_pos;
set(gca,'CameraPosition',camera_pos);
final_angle = 2.5*atand(r/1);
set(gca,'CameraViewAngle',final_angle);
end
drawnow

3D visualisation with VTK/paraview

Here is my problem :
I have a 2D domain (say a square) divided in triangles in a unstructured manner. On each triangle (denoted T), I define a constant scalar, denoted f(T).
I want to plot the surface (T,f(T)) using Paraview.
So I have created a vtk file like this:
vtk DataFile Version 3.1
my personnal comment here
ASCII DATASET UNSTRUCTURED_GRID
POINTS 4 FLOAT
0 0 0
0 1 0
1 0 0
1 1 0
CELLS 2 8
3 0 1 2
3 1 2 3
CELL_TYPES 2
5 5
CELL_DATA 2
SCALARS Namedata double
LOOKUP_TABLE default
2
-5
I would like to see (thanks to Paraview) a 3D plot. Ideally, the visualization on this example should be two triangles: the first one should have its z-coordinates equal to 2 and the second one should have its z-coordinates equal to -5. I don't know if something is possible or if the vtk format is the good one for what I'm trying to do.
If it is not possible, I would be happy to represent only the two points (x-coordinate of the triangle number 1, y-coordinate of the triangle number 1, z-coordinate = 2) and (x-coordinate of the triangle number 2, y-coordinate of the triangle number 2, z-coordinate = -5) with or without interpolation.
This is not hard to do in ParaView. There is filter named "Warp By Scalar" which can translate geometry in the z direction (or any other direction) based on a scalar field. The only issue is that Warp By Scalar works on point data, and you want to warp by cell data. So you have to go through a few steps first.
Add the "Shrink" filter to your data. Set the "Scale Factor" parameter to 1. Apply. Your data will look the same, but it will have the effect of breaking apart the triangles, which are actually sharing points in your original data.
Add the "Cell Data to Point Data" filter to the output of the Shrink filter. Apply.
Add the "Warp By Scalar" filter to the output of Cell Data to Point Data. Apply.

I don't know hot to plot this nonlp's feasible reagion in matlab

I searched and watched how to plot the 3 dimensions of nonlp program's
but I still don't know how to plot these constraints.
x^2+y^2+z^2=1
x>=2*y
2*y>=3*z
x>=3*z
I programmed like this but it doesn't work and I think this is wrong program for upper constraints.
func1 = #(x,y,z) sqrt(1-x.^2-y.^2);
func2 = #(x,y,z) max(x-2*y,0);
func3 = #(x,z) max(x-3*z,0);
ezsurf(func1,[0 1 0 1]);
hold on;
ezsurf(func2,[0 1 0 1]);
hold on;
ezsurf(func3,[0 1 0 1]);
axis([0 1 0 1 0 1]);
A way of doing that is to work with volumetric data.
The idea is to create a 3D space, with a F value. F will be positive in one side of your main equation and negative in the other.
[X,Y,Z]=meshgrid(-2:0.05:2,-2:0.05:2,-2:0.05:2);
F=X.^2+Y.^2+Z.^2-1;
Then the conditions are applied to this F. If you want to see the object "cut"
then substitute the place where conditions are not met with nan. If you want to see a filled object, then substitute it with a positive number (it may need to be negative in another situation, so check this for other examples.
% Conditions
cond1=X>=2*Y;
cond2=2*Y>=3*Z;
cond3=X>=3*Z;
% If you want the boundaries to show
F1=F;
F1(~cond1)=1;
F1(~cond2)=1;
F1(~cond3)=1;
% If you want the boundaries not to show
F2=F;
F2(~cond1)=NaN;
F2(~cond2)=NaN;
F2(~cond3)=NaN;
Then the idea is to create an isosurface in the zero level (your original function). Here in this code I created 2 plots so you can see the differences between filling and not filling the boundaries. Also some fancy coding in order to get nice figures. However the isosurface and patch parts are relevant to obtain the surface and plot it.
subplot(121)
iso1=isosurface(X,Y,Z,F1,0);
p=patch(iso1);
isonormals(X,Y,Z,F1,p);
set(p,'FaceColor','red','EdgeColor','none');
daspect([1 1 1])
axis equal
camlight
lighting gouraud
subplot(122)
iso2=isosurface(X,Y,Z,F2,0);
p=patch(iso2);
isonormals(X,Y,Z,F2,p);
set(p,'FaceColor','red','EdgeColor','none');
axis equal
daspect([1 1 1])
camlight headlight
lighting gouraud
Result:
Additionally, You can calculate the isosurface of the initial boundary F and plot it with a low alpha value, so you can better understand what piece of the domain you are actually selecting.

Ask for plotting rectangular pulse with controlled rising/falling edge

I would like to plot a series of rectangular pulse to a vector data input. The plot profile would create a rising edge of the pulse for a positive number and create the falling edge for the negative of that number. The plot should separate color for each represented number.
For example, if vector input X is [1 -1 2 -2 3 4 1 -4 -1 -3]
Amplitude of data ‘1’ is 5,
Amplitude of data ‘2’ is 4,
Amplitude of data ‘3’ is 3 and
Amplitude of data ‘4’ is 2
So, the input X got index from t(1) to t(10). The output of plot or chart should look like the inserted image
How would I can write a MATLAB code for this work?
Thank you.
B.Bundit
The plot is very small but I think you want something like bar in matlab. Documentation is here. If the vector that you have is changes then you can create a vector of values for plotting using cumsum.
X=[1 -1 2 -2 3 4 1 -4 -1 -3];
Xplot=cumsum([5,X(2:end)]); % //so 5 will be your initial value
Since the plot you give above has different widths of bars, you would also need a vector of the center of each data point and the width of each data point.
means= [1 2 3 4 5 6 7 8 9 10];
widths=[1 1 1 1 1 1 1 2 1 1];
For different color bar plots you can do:
colors=['r','g','k','b','c','m','y','r','g','k'];
for i=1:length(X)
h=bar(means(i),Xplot(i),widths(i));
if i==1, hold on; end
set(h,'FaceColor',colors(i));
end
% //This will label each bar, or you could define your axes before the loop
set(gca,'XTickLabel',means);
You can explore other properties to set here. The class barseries does not have a FaceAlpha property so I'm not sure if you can make them transparent. You could however set the FaceColor to none and have the EdgeColor be set to your color of choice. Note that edge color is specified by an RGB triplet and not a letter code.
You may also need to resort your data by width, so that the widest bars are plotted last and are thus on top. This would look like this:
[widths_sorted,sort_idx]=sort(widths,'ascending');
Xplot_sorted=Xplot(sorted_idx);
means_sorted=means(sorted_idx);

semilog plot: axes will not stay consistent

I am trying to get 5 different semi log x figures for 5 data sets (and each figure has a number of lines on its plot). The plot works well when I don't enter any data (i.e. the axis ranges are what I want them to be) but when I enter data, the axes ranges changes (the limits stay the same, but the spacing between different values changes). For example, for the first data set, I input it and 10^2 appears about 1/4 of the way across the x-axis, but I input the second data set and 10^2 appears 1/2 of the way across the x-axis. How can I get the axes to stay perfectly consistent regardless of whether the data changes?
My code is below:
function createfigure_log_orient_autocorr(X1, YMatrix1)
plot(X1,YMatrix1,'LineWidth',2);
set(gca,...
'YTickLabel',['0 ';'0.2';'0.4';'0.6';'0.8';'1 '],...
'YTick',[0 0.2 0.4 0.6 0.8 1],...
'XTickLabel',['0';'1';'2';'3'],...
'XTick',[1 10 100 1000],...
'XScale','log',...
'XMinorTick','on',...
'PlotBoxAspectRatioMode','manual',...
'PlotBoxAspectRatio',[1.999 1 0.5],...
'FontWeight','bold',...
'FontSize',16,...
'DataAspectRatioMode','manual',...
'DataAspectRatio',[1000 1 2],...
'XLimMode','manual',...
'XLim', [0 2000],...
'YLimMode', 'manual',...
'YLim', [0,1]);
I understand my question may be confusing, so I can try to clarify if anyone needs me to.
I'd use the function semilogx(...) instead of plot, and then follow it up with axis to set the limits I want.
More here.