Gnuplot find local maximum of 3D data - sed

I have a problem in gnuplot...
I am making an splot from my data points which are discrete "lines" (see attached pic) among y values of 1,1/2,1/3 etc...
At every discrete "line" I would like to get the maximum Z value and its X and Y coordinates, and highlight them, or maybe fitting a function on them etc...
Here is my code:
set title "1/m vs mutation rate"
#set term pdfcairo size 6,4
set term x11
set xlabel "Mutation rate"
set ylabel "1/m"
set xrange[0.0001:0.05]
set yrange[1.0/30:1]
unset log x
set cbrange[0:0.35]
set zrange[0:1]
set palette defined ( 0 "green", 1 "blue", 2 "red")
#set view 78,348,1,1
set view map
set output "muemmeres500map.pdf"
splot 'muemmeres500.txt' u 1:2:3 with points pt 5 ps 1 palette, "muemmeres500.txt" every 30 using ($3==GPVAL_DATA_Z_MAX?$1:NaN):($3==GPVAL_DATA_Z_MAX?$2:NaN):3 title "max1" lc rgb'black' lw 4, "muemmeres500.txt" every 30::2 using ($3==GPVAL_DATA_Z_MAX?$1:NaN):($3==GPVAL_DATA_Z_MAX?$2:NaN):3 title "max2" lc rgb'black' lw 4, "muemmeres500.txt" every 30::3 using ($3==GPVAL_DATA_Z_MAX?$1:NaN):($3==GPVAL_DATA_Z_MAX?$2:NaN):3 title "max3" lc rgb'black' lw 4, "muemmeres500.txt" every 30::4 using ($3==GPVAL_DATA_Z_MAX?$1:NaN):($3==GPVAL_DATA_Z_MAX?$2:NaN):3 title "max4" lc rgb'black' lw 4, "muemmeres500.txt" every 30::5 using ($3==GPVAL_DATA_Z_MAX?$1:NaN):($3==GPVAL_DATA_Z_MAX?$2:NaN):3 title "max5" lc rgb'black' lw 4
unset output
And here is the data file: http://pastebin.com/umqGWtyy
As you can see in the picture, the "lines" data points correspond to each line in the datafile, so for instance the data points starting with the first then every 30 correspond to the "line" which has a y value 1, then from the second line every 30 corresponds to the "line" which y value is 1/2 etc...
Therefore I wanted to get the maximum Z value from just those data...
I tried sed as well, but I failed...
So my problem is, that it can just find the global maxima and not the other local ones...:( pls help me:)
Here is the picture:
I have no idea... hope it is understandable and sorry for my english...:)

GPVAL_DATA_Z_MAX doesn't seem to work for your problem but you can use stats instead to find all the local maxima and then plot them all in a looped plot.
#Do it before setting the ranges (the column will be handled as an x column and it might get out of xrange)
do for [i=0:28]{
#Give an indexed prefix to each stat (so they *all* become accessible from outside the loop, like "A12_max" or "A25_min")
stats 'muemmeres500.txt' every 30::i u 3 nooutput prefix "A".i
}
#set all the things you need for the plot (including ranges)
...
splot 'muemmeres500.txt' u 1:2:3 with points pt 5 ps 1 palette, \
for [i=0:28] '' every 30::i u 1:2:($3==value("A".i."_max") ? $3 : NaN) notitle #t "Max".(i+1)
Note: the indices used by every start from zero.
This only works for plotting, you have all the maxima but you don't have the X and Y coordinates yet.
You also have the indices of the maxima so if you can retrieve the X Y values from the A<n>_index_max row (actually its 30*index+i or the nth block's ith row ) you have the nth maximum position. To retrieve the nth row you can use stats again with every.
do for [i=0:28]{
stats 'muemmeres500.txt' every ::i:value("A".i."_index_max"):i:value("A".i."_index_max") u 1:2 nooutput prefix "P".i
}
If you do this right after getting the Ai_ stats you already have all the positions P<i>_max_x P<i>_max_y and Z values A<i>_max.
If you want you can print them to a file:
set print "maxima.dat"
do for [i=0:28]{
print value("P".i."_max_x"), (value("P".i."_max_y")), (value("A".i."_max"))
}
unset print

Related

Wrong dendrogram generated

I have 31 data, but dendrogram is missing one data. Here is my code:
A = csvread('similarityNoGrpS2.csv',1,1) % 31x31 double
Z = linkage(A, 'average') % 30x3 double
H = dendrogram(Z,'Orientation','left','ColorThreshold','default') %29x1 line
My input file can be found here.
Here is my dendrogram:
According to Z, (24,30) and (27,31) should be clustered, but in dendrogram pic, we can see there is no 31 and 27 is getting clustered with 30 which is wrong!
Can anyone help me in this matter?
P.S. I'm using MATLAB R2016a.
You need to modify the last line of your code to this:
H = dendrogram(Z, 0, 'Orientation', 'left', 'ColorThreshold', 'default');
which for the given data gives:
Explanation
Your original data set (A) has more than 30 points but you did not specify the value of P. It is mentioned in the documentation:
If you do not specify P then dendrogram uses 30 as the maximum number of leaf nodes. To display the complete tree, set P equal to 0.
So you need to put P=0 in this syntax:
dendrogram(tree,P,Name,Value)

Plot range for line of fit using date on the x-axis in gnuplot

I am trying to plot the fit function (col 3 versus col 7) for my dataset given below
28-08-1991 20-12-1992 24-04-1992 -263347200 -221875200 -242611200 0.060859
20-12-1992 02-09-1993 27-04-1993 -221875200 -199756800 -210816000 0.064681
10-09-1996 13-09-1997 13-03-1997 -104371200 -72576000 -88473600 0.095728 ......
I would like my script to plot the fit only for certain range of dates, say between 1995 to 2003. I am unable to get the range function right since the gnuplot handle the dates past the year 2000.
Please find my code below.
set xdata time
set timefmt "%d-%m-%Y"
set xrange ["01-01-1991":"01-01-2015"]
set yrange [0.0:0.4]
offset = 24*60*60
f(x) = 1.e-7*m*(x-offset)+c
fit f(x) "file" using 3:7 via m,c
set fit logfile 'file.log'
plot '(x < "24-02-1993" ) ? f(x) : 1/0' title "Best fit" with lines ls 5
The variable x in plot will contain the time in the form of seconds since 1/1/1970. So in order to compare it with a date, you need to convert that date to the same format with strptime.
If you additionally remove the ' around the function to plot in your MWE, you get:
plot (x<strptime("%d-%m-%Y","24-02-1993"))?f(x):1/0 title "Best fit" with lines ls 5
Note that you've fitted f(x) over the whole dataset, not over dates before 24-02-1993, it's only the plot which is restricted to these dates.

Extract and display result from table MATLAB

I am trying to extract the lowest value for V from the table produced for each force (F) in order to establish the optimum result, e.g. for F=5000, V=0.06575 is the optimum result.
I want to be able to display this for each instance of F. I'm not quite sure where I am going wrong.
%===========================================
%This Script calculates
%===========================================
%Parameter Values
%F:force (N)
%L1: Length of beam 1 (m)
%L2: Length of beam 2 (m)
%H: Height of beam 1 (m)
%h: Height of beam 2 (m)
%b: Cross section width (m)
%S: Yield strength (Pa)
%N: Factor of safety
%V:Volume of the beam (m^2)
%=========================================
clc %clear command window
clear all %clear all variables previously generated and stored in Matlab
format short g
L1=2;
L2=3;
b=0.05;
S=248;
K=1.42;
results=[];
optimalresults=[];
nd=3.6; %desired factor of safety calculated by group number
for F=5000:100:6000
for h=0.2:0.005:0.3 %loop of h
for H=0.2:0.005:0.3 % loop of H
M1=F*(L1+L2);
M2=F*L2;
I1=b*H^3/12;
I2=b*h^3/12;
Y1=H/2;
Y2=h/2;
Max_stress_1=M1*Y1/I1;
Max_stress_2=K*(M2*Y2/I2);
Max_total_stress=max(Max_stress_1,Max_stress_2);
Max_total_stress=Max_total_stress/1e6;
N=0.577*S/Max_total_stress;
%if N is greater than desired factor of safety then display results
if N >= nd
V=(b*L1*H)+(b*L2*h);
results=[results; F,V,N];sort(F);
end
end
end
results_sorted=sortrows(results,1); %sorts factor of safety from min to max
disp(' F V N');
disp(results_sorted);
optimum=results_sorted(1,:)
end
What do I have to change to display the minimal value of V for each F?
My guess is that you probably want this bit outside of the 3 for loops:
results_sorted=sortrows(results,1); %sorts factor of safety from min to max
disp(' F V N');
disp(results_sorted);
optimum=results_sorted(1,:)
Also, I am not sure what you achieve with sort(F); inside the loop.
I think your code needs two changes before you can get the minimal value of V for each F:
Where you use sortrows, you should sort the table using the second column (V), so that the lowest V gets placed in the top row. results_sorted=sortrows(results,2);
You should sort only the results for the current F, so either you clear the variable "results" for each F iteration results=[]; or you use a new variable. Be sure to check if "results" is not empty before sorting the rows.
The variable "optimum" has now the lowest V for each F iteration.

Matlab display a variable from function

I'm new to Matlab and I have a function and I need to display a variable from running the main file (but the main file does access the function)...
I have tried to use fprintf(n);
Thanks :)
MATLAB function fprintf() is very similar to fprintf() in C. If your variable n is an integer, then you should do
fprintf('%d\n', n);
An interesting feature is that you can also print multiple numeric values and literal text to the screen. For example
A1 = [9.9, 9900];
A2 = [8.8, 7.7 ; ...
8800, 7700];
fprintf('X is %4.2f meters or %8.3f mm\n', A1, A2);
where %4.2f takes the element at the first column of A1 and %8.3f takes the second. In the sequence, it repeats for A2 printing its first line and later its second line. The output is
X is 9.90 meters or 9900.000 mm
X is 8.80 meters or 8800.000 mm
X is 7.70 meters or 7700.000 mm
If you want more details about the specifiers you can use with fprintf(), you should give a look at the MathWorks docs.

gnuplot: Is it possible to plot the (x, y) coordinate besides each point?

I found an answer here about using labels with the points but that only works for 1 column with the label, whereas in order to plot (x, y) along with the point I have to use 2.
So I need something along the lines of plot "data.txt" using ($1):($2):1:2 with labels, "data.txt" using 1:2 with ($1):($2):1:2 being (x):(y) the coordinate for the point on the image and 1:2 being the label, except that doesn't work since it isn't a valid syntax and so only the first value is plotted at the correct location.
Well I guess I can use something like plot "data.txt" using ($1+2):($2+2):1 with labels, "data.txt" using ($1+10):($2+2):2 with labels, "data.txt" using 1:2 to manually set the spacing but damn is that ugly/low-level/hackish/bad/etc.
how about this:
set key off
get_point(x,y) = sprintf("(%.0f,%.2f)", x, y)
offset(y) = (y<0.5) ? (y - 0.05) : (y + 0.05)
plot [-1:6] "-" u ($1):(offset($2)):(get_point($1, $2)) with labels, "-" u 1:2 w l
0 0.20323
1 0.19147
2 0.50213
3 0.17599
4 0.07732
5 0.66897
e
0 0.20323
1 0.19147
2 0.50213
3 0.17599
4 0.07732
5 0.66897
e
What it does:
With the get_point macro you can easily form a string which will be your x- and y-coordinates. The offset function is simply to move the labels a bit away from the curve. This might be useful if you data has a specific form (like in this case a global mean value of 0.5).
Of course the script looks nicer, if you use a datafile instead of having the data in the plot file.