Flip data for use in graph upside down with intervals unchanged (exactly as in picture attached) - matlab

I am using MATLAB and need to flip data in a graph upside down as in pic below;
I.e. I have vector A = [1 2 3 4 4 4 3 3 3] (blue line) and I need to transform it exactly into B = [4 3 2 1 1 1 2 2 2] (red line). Note that I need the interval of the x- and y-axis to be unchanged. I have tried flipud, fliplr, flip and rot90, without any success.
Please note that I need to transform the data itself (it is not enough to flip the image upside down).
Stuck for a while, any help is much appreciated!

Mathematically, it is the following transformation:
B = -A + min(A) + max(A);

Related

How to triangulate a polygon with and without vertices and holes inside - delaunay triangulation possible?

I got the following problem: I'm working on an algorithm and the output will be an arbitrary polygon. The polygon can be concave, have holes in it and also have vertices with edges that have an angle of 180 degree.
I need to triangulate said polygon with and without additional vertices inside it. Can the delaunay triangulation handle this, especially if I only have the polygon without vertices inside? I might be able to avoid holes inside the polygon, if that eases things.
Thanks for reading
You might have a look at these Fade2D examples:
https://www.geom.at/example4-zones-defined-areas-in-triangulations/
https://www.geom.at/boolean-operations-on-polygons-with-holes/
The student license is free.
You can do that using a constrained triangulation (Delaunay or not) to triangulate a polygon. There is an example using CGAL here.
You can use Triangle.
Running Triangle via the command line, you create an ASCII .poly file that specifies the vertices and edges of the input (i.e., your polygon) as well as any holes in the domain. Each hole is defined by its xyz location. For example, if I have a square domain with a triangular hole inside it, my input could look like:
7 2 0 0 # 7 vertices
1 1 -1
2 1 1
3 -1 1
4 -1 -1
5 -.5 -.5
6 .5 -.5
7 0 .5
7 0 # 7 segments: four for the square and three for the hole
1 1 2
2 2 3
3 3 4
4 4 1
5 5 6
6 6 7
7 7 5
1 # 1 hole
1 0.0 0.0
If you want to refine the mesh (i.e., add vertices inside), you can use either the -a option (limiting the maximum area of a triangle) or the -q option (controlling the quality of the triangles produced but not directly limiting the size). The documentation on command line switches is here.

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

making a single stacked bar with colors from each stack depending on the distribution frequency

I have a vector of the size 10000x1, which I reduced to 4400x1. I want to make a stacked bar with the single entries of this vector. Each segment of the stacked bar should be colored depending on the distribution frequency. For example: if a value is represented 10 times, it should almost be black. if its only 1, it should be light grey.
1st problem: When I use a small vector, I get a stacked bar. If I use the one I need to I get multiple bars instead of one stacked bar.
2nd problem: How can I make the bar use a gray scale to color them?
I tried to transpose my vector to 1x4400 which didn't change anything.
I used bar(data,'stacked') which works for the small vector (at least I get a stacked bar. To get a single bar I used:
test = [1 2 3 4 5 1 2 3];
bar([test; nan(size(test))],'stacked');
size of data : 4400x1
bar([data; nan(size(data))],'stacked');
When I enter your first example, with an 1x8 matrix:
test = [1 2 3 4 5 1 2 3];
bar([test; nan(size(test))],'stacked');
I see the same plot you see. Then I transpose test to make it an 8x1 matrix:
test = test.';
bar([test; nan(size(test))],'stacked');
and I see something similar to your second plot:
Note how the NaNs cause the right half of the x-axis to have no bars.
Thus, to get stacked bars you need to have a row vector. However, your data is a column vector, a 4400x1 matrix. data = data.' will change that.
Nonetheless, it is likely that MATLAB is not able to make a stacked bar plot with 4400 elements. I'm trying this out on MATLAB Online, and I've been waiting for several minutes and still don't have a plot. In any case, there is no way you would become any wiser with such a plot. Don't do it!
Regarding your second question: you can change the plot color order to gray:
set(gca,'colororder',flipud(gray(256)))
However, the stacked bars are not colored according to their value, they just use the colors of the list in turn.
A better solution would be to plot your data as an image:
test = [1 2 3 4 5 1 2 3];
imagesc(test.')
colormap(flipud(gray(255)))
set(gca,'xlim',[0,2],'xtick',1)
[I just realized you might want to straighten the y-axis, imagesc inverts it. Simply: set(gca,'ydir','normal').]

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.

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);