Gnuplot loop with different axis - loops

I just discover gnuplot 4.6 and the beautiful loop tool.
I want to plot a curve with different x axis, but it doesnt work.
I have a file called file.txt, where there is a list of data like :
E002 = ...
E003 = ...
.
.
.
E021 = ...
The point is to shift the x axis of each plot with the corresponding data, something like this :
load 'file.txt'
plot for [a=2:21] 'my_data_file.dat' u ($1+'E00'.a ):a w l
But this doesn't work, and I have the error : 'Non-numeric string found where a numeric expression was expected'.
I do not know how to bypass this issue.
Second question,
i would like after to sum all the column but shifted like before. Something like :
($1+E002):$2 + ($1+E003):$3 +...
Is there a way to do that ?

For the first question, you need to use the value to get the value of a variable.
I suggest to use a more versatile sprintf command to manipulate strings:
plot for [a=2:21] 'my_data_file.dat' u ($1+value(sprintf('E%03d',a))):a w l
Type help value and help sprintf to get more info about those commands
I don't understand very well the second question, maybe something like this could help?
my_sum=0
plot for [a=2:21] my_val=value(sprintf('E%03d',a)), my_sum=my_sum+my_val, 'my_data_file.dat' u ($1+my_val):a w l
print my_sum
the last line, should print the sum of all you Exxx values.

Related

Declaring two arrays in gnuplot and plotting them one with respect to another

Gnuplot version 5.2 supports arrays. As given here, one can declare 1D arrays and plot them
array A[100]
do for [i=1:100] { A[i] = sin(2*pi*i/100.) + 0.1*rand(0) }
plot A
This plots the matrix A with the index i.
Is there a way to have two 1D arrays (Eg: x and y) and plot them y vs x.
OR
Declare a 2D array A and plot the 2nd column of A with respect to the first column of A?
Answer #2
If the two arrays A and B are guaranteed to have the same size, a simpler plot command is possible. We start by noting that all of the following plot commands are equivalent.
plot A
plot A using 1:2
plot A using (column(1)):(column(2))
plot A using ($1):($2)
plot A using ($1):(A[$1])
This is because for purposes of plotting an array A is treated as providing two columns of information, the index i (column 1) and the value A[i] (column 2). Following standard gnuplot syntax, each field in the "using" specifier of a plot command may contain either a bare column number or an expression in parentheses. Inside an expression the value of a column can be referred either by prefixing a $ sign or by using the function column(i).
With this in mind, it follows that the command below plots the values of array B against the values of array A.
plot A using (A[$1]):(B[$1])
The trick is to have gnuplot generate a set of samples to plot. Instead of a filename you can provide the string '+' to generate a set of samples along one dimension or '++' to generate a set of samples along two dimensions. Gnuplot calls these "special file names". In your case you want to generate 100 samples (integers from 1 to 100) and use each sample as an index into your arrays.
array A[100]
array B[100]
do for [i=1:100] {
A[i] = something
B[i] = something else
}
plot sample [i=1:100] '+' using (A[i]):(B[i]) with linespoints
The keyword "sample" guarantees that the term in square brackets will not be mis-interpreted as setting the horizontal range ("set xrange") of the plot.
Documentation entries
help +
help special-filenames
help sampling
Answer #3
You ask whether there is an alternative to make A a 2-dimensional array. Not exactly, but remember that in gnuplot floating point numbers are actually complex values. So you could use the real and imaginary components of each A[i] to place it in the x/y plane:
array A[36]
set angle degree
i = {0,1} # i = sqrt(-1) as a complex value
do for [n=1:36] {
A[n] = cos(real(10.*n)) + i * sin(real(10.*n))
}
plot A using (real(A[$1])):(imag(A[$1])) with lp
Is there any special reason why you want to have data in arrays first?
As you are filling your arrays with values of functions, you can also plot two functions (or as you say two columns of a 2D-array) directly against each other without first defining arrays in a do for loop.
Just define some functions and plot them against each other.
Use set samples to define the number of points and use plot sample [] for setting the range. I guess this would be easier than setting the array size, doing the loop and "messing" around with the index i and the range and/or offsets.
### plot one function vs. another function
reset session
f(x) = sin(x) + 0.1*rand(0)
g(x) = cos(x) + 0.1*rand(0)
set samples 100
plot sample [0:2*pi] '+' u (f($1)):(g($1)) w lp pt 7 lc rgb "red"
### end of code

R Programming: 3D array plots

I am trying to do up a 3D array plot in R.
I already have an array built up and defined with the corresponding z-values
e.g. CVHSP500 = array(0,c((nHSP500-N),N))
So now I am trying to do a 3D array plot with it. I decided to go with persp3d(CVHSP500,col = "lightblue",) and have obtained a rather decent plot.
3D Image
So there are obviously some issues with this plot.
1) The coordinates are not defined correctly.
Reading up online on the usage of persp3D, and other R programming functions/packages like slice3D, they all require x, y and z to be separate list.
I don't understand how to match the values of x and y to the respective z, and since persp3D works perfectly without me having to do that, I decided to use persp3D.
But I will need to insert coordinates for it, but I have no idea how to.
2) Any advice how do I color the plots for different ranges of z?
The ones online all seem to have to refer to individual x, y and z lists and some form of advanced modification which I can't really understand. This light blue color looks okay but it would be good for different ranges of z as well though.
Thanks for the help. Much appreciated.
To transform a 2D array representing z for each (x,y) into 3 vectors x, y and z, you can do this:
CVHSP500 = array(0,c((nHSP500-N),N))
x <- rep(1:(nHSP500-N),N)
y <- rep(1:N,(nHSP500-N))
z <- CVHSP500
dim(z) <- (nHSP500-N)*N

gnuplot for loop with interval

I have the following gnuplot script that uses a for loop to plot 100 data sets of (x,y) format to one plot. However, the script only plots 2 data sets. Can anybody help? Thank you.
plotfile = "graph.eps"
set output plotfile
filename(n) = sprintf("%d_mod.int", n)
plot for [i = 400000:4000000:400000] filename(i) u 1:2 title sprintf("%d", i) w lp
That is a bug, which will be fixed in 4.6.6 and 5.0, see #1429 Erratic behaviour of do for loops .
As a workaround you must iterate over smaller numbers:
plot for [i = 4:40:4] filename(i*100000) u 1:2 title sprintf("%d", i*100000) w lp

Plotting from a 2D Array Using a Loop

This seems like a trivial problem, though I've been hitting myself over the head with it for too long.
This doesn't even plot just the (0,0) -- I can't seem to find much about plotting from arrays -- rather just matrix plots (and only columns at that).
The data is properly in these arrays, I just need to make plots! Doesn't seem so complicated. I don't even need separate colors for the different sets...just all one big scatter plot.
Any suggestions?
pdf(mypath)
# Plot first point
plot(0,0, col = "blue", type = "n", xlab="PES", ylab=""%eff")
#Loop to Plot remaining points
for(rows in 1:nrowX)
{
for(cols in 1:ncolX)
{
points(X[rows,cols],Y[rows,cols], col = "blue", type = "p")
}
}
dev.off
I have also tried using plot.new() to have an empty plot...but no such luck.
SOLUTION!!
Turns out I'm just a fool. Code is acurate and the suggestions below do indeed work.
R happened to be open in another tab and since it was open, never let go of the plot (why? I don't know). As soon as it was closed, the plot appeared. Now I can get my plot again and again...
Thanks to everyone who tried helping a problem that wasn't a problem!
I like this place already!
When you set type = "n", the plot function will not plot anything at all. It is used to set up a basis for the rest of the plot (like axis labels, limits etc). That is why the first point at (0, 0) does not show up.
The rest of the points are probably outside the range. Use xlim and ylim to set up the ranges properly. I'm going to assume X and Y have the same size and dimension. Try this:
pdf(mypath)
# Set up the plot
plot(0, type="n", xlab="PES", ylab="%eff", xlim=range(X), ylim=range(y))
# Now plot
points(X,Y, col="blue")
dev.off
Of course you could let the plot function take care of the limits for you:
pdf(mypath)
plot(X, Y, xlab="PES", ylab="%eff")
dev.off()
Your initial plot will set up the coordinates, but since you only give it one point it does not know how much room to leave around the 0,0 point (so it does not leave very much). I expect that the rest of your points fall outside of that range which is why they don't show up on the plot (you can use par("usr") to see what the extents are).
When you create the initial plot you should include xlim and ylim arguments so that the plot includes the area where the new points will be added, something like:
plot(0,0, type='n', xlim=range(X), ylim=range(Y))
You may also be interested in the matplot function which will take a matrix as either or both the x and/or y argument and plot accordingly.
Edit
The following works for me:
X <- matrix( runif(390), nrow=10 )
Y <- matrix( rnorm(390), nrow=10 )
plot(0,0, col = "blue", type = "n", xlab="PES", ylab="%eff",
xlim=range(X), ylim=range(Y))
#Loop to Plot remaining points
for(rows in 1:nrow(X))
{
for(cols in 1:ncol(X))
{
points(X[rows,cols],Y[rows,cols], col = "blue", type = "p")
}
}
I did remove an extra " from the ylab, was that your problem?
But
plot(X,Y)
also worked without the looping.
Check with just the console to see if it works before worrying about sending to a pdf file. If this has not fixed it yet, we still need more details.

Why am I getting weird vertex position values in MaxScript

I am trying to write a simple mesh exporter in maxscript. It's nothing fancy, it just has to export faces, vertices and tvertices. I have the code as good as working, but sometimes I get really weird values in vertex positions (-1.1234e-005 for example). I understand it is some kind of really big number, but the problem is, my verts aren't anywhere near the position that number indicates (I have seen this happen with a 1m*1m*1m box). I have found that when it happens with a mesh, it always happens with that mesh and with the same vertex, untill I move that specific vertex (scaling/moving the whole thing doesn't work). I use this code to export the vertex positions:
num_verts = sel_mesh.numverts
for i=1 to num_verts do (
v = getVert sel_mesh i
format "v %\n" v to:out_file
)
format "\n" to:out_file
I have tried Googling the problem, but no one seems to have the same issue. I use the same code for my tvertices and those are exported perfectly fine. I can post the whole exporter if neccesary. Please let me know if you need to see more code :).
This is infact a very small number.
-1.1234e-005 is -1.1234 * (10 ^ -5), which is very small.
Contrary to your comment, formattedPrint does 'fix' this.
formattedPrint -1.1234e-005 format:".6f"
output: "-0.000011"
You can use it as such in your exporter:
num_verts = sel_mesh.numverts
for i=1 to num_verts do (
v = getVert sel_mesh i
format "v %\n" (formattedPrint v format:".6f") to:out_file
)
format "\n" to:out_file

Resources