I have two columns in my data file:
x y
1 5
1 10
2 3
4 5
4 6
4 14
That is I have a set of results (y values) for particular value x. I want to produce a graph with gnuplot that shows all the data points shown above and a curve that goes through their average values:
x y
1 (5+10)/2
2 3
4 (5+6+14)/4
This should be fairly simple but I can't find it.
How can I do that?
plot "datafile" u 1:2 smooth unique
does exactly what you want.
Related
I have two different .txt files with x and y coordinates of equal number of samples in both.
File 1
x y
1 2
5 4
4 6
File 2
x y
5 6
3 4
2 3
I want to connect each of these points inFile 1 with the corresponding points in File 2. I know to draw an arrow between two points it is
set arrow from (x,y) to (c,d)
But how do I get the coordinates of these points from two different files to draw connecting lines/ arrows?
Something like this:
plot "< paste file1.data file2.data" with vectors
Edit: I came across this old answer and was amazed (actually shocked) how inefficient and complicated solutions I suggested.
A much better approach: Since gnuplot 5.2.0 you can index datablocks. Prerequisite is that your data is in a datablock already. See here: gnuplot: load datafile 1:1 into datablock.
If you can be sure that your data files have identical number of lines, you can "mimic" the Linux paste command using a gnuplot-only, hence, platform-independent solution.
Basically, you join the two lines having the corresponding index after removing the last character (newline) of each line.
Script: (works with gnuplot>=5.2.0, Sept. 2017)
### plot arrows across two files, i.e. merge lines with gnuplot only
reset session
$Data1 <<EOD
File 1
x y
1 2
5 4
4 6
EOD
$Data2 <<EOD
File 2
x y
5 6
3 4
2 3
EOD
set print $Combined
do for [i=1:|$Data1|] {
print $Data1[i][1:strlen($Data1[i])-1].' '.$Data2[i][1:strlen($Data2[i])-1]
}
set print
plot $Combined u 1:2:($3-$1):($4-$2) w vec lc rgb "red"
### end of script
Result:
I have a file where my data are separated into several indexes. I would like to plot some or all of the indexes as stacked filledcurves by adding the values of selected previous indexes to the values of the current index. I could not find a way to use the sum function as in the case of data arranged as columns in a single index (as in this question), even using the pseudocolumn(-2) as the index number.
Important note: every index as strictly identical sets of x values, only the y values differ.
Is there a way to do something like
p 'data.dat' index (sum(ind=1,3,4,5) ind) u 1:2 w filledcurve x1 t 'Sum(1,3,4,5)', '' index (sum(ind=1,2,5) ind) u 1:2 w filledcurve x1 t 'Sum(1,2,5)'
within gnuplot or do I have to resort to a script (maybe a variation of the one in this answer)?
You can do this with some help outside gnuplot (invoked within gnuplot). Imagine you have the following data file with 4 indices (0 to 3):
1 2
2 3
1 5
2 5
1 0
2 3
1 4
2 3
Now say that we want to sum 1 and 2 and 0 and 3. The first sum should return:
1 5
2 8
while the second sum should return
1 6
2 6
We can select the blocks we want using set table:
set table "sum1"
plot for [i in "1 2"] "data3" index 0+i pt 7 not
set table "sum2"
plot for [i in "0 3"] "data3" index 0+i pt 7 not
unset table
Now use sed piping to remove the empty lines and smooth freq to sum for equal x values:
plot "< sed '/^\s*$/d' sum1" smooth freq t "sum1", \
"< sed '/^\s*$/d' sum2" smooth freq t "sum2"
Although you may be able to do it using functions and variables of gnuplot 4.4+, this won't be very efficient as you want to perform an operation on several distant lines in your file, which is in fact an operation on arrays. Gnuplot is not meant for this, the datafiles should have a structure reasonably close to what you want to plot. I advise that you try to produce a file with such a structure, e.g. have the values you want to sum on the same line in different columns.
I have the below data in gnuplot:
2012-09-18 0 2 12
2012-03-15 1 4 5
2012-12-18 24 8 11
2012-09-18 2 8 11
2012-03-15 16 5 5
2011-12-06 5 2 3
2012-12-18 3 12 8
2012-09-18 4 4 8
2012-03-29 11 6 2
2011-12-06 9 7 3
2012-12-18 6 7 8
2012-09-18 4 3 8
2012-02-09 27 2 1
2012-12-18 2 1 8
2012-09-18 6 14 8
1st column; x (date)
2nd column; y
3rd column; the point color
4th column; number of occurrences(the point is duplicated)
I need to write a gnuplot program which:
Draws my (x,y) points.
Gives each point a different color depending on the 3rd column value (maybe over 50 different colors).
If the 4th column is greater than 0 then the point is duplicated and it must be drawn n times and give its x,y a random positing with a small margin. for example, (rand(x)-0.5,rand(y)-0.5).
Another question, what is the best and fastest way/tool to learn gnuplot?
This is supposed to be an extension to my answer for your other question drawing duplicated points in gnuplot with small margin:
You need to have the first column interpreted as time data. For this you need
set xdata time
set timefmt '%Y-%m-%d'
In order to set the point color, it is best to define a palette and then use linecolor palette, which sets the point color based on its value in the palette.
So, using the explanations from drawing duplicated points in gnuplot with small margin the final script is:
reset
filename = 'data.dat'
stats filename using 4 nooutput
set xdata time
set timefmt '%Y-%m-%d'
set format x '%Y-%m'
rand_x(x) = x + 60*60*24*7 * (rand(0) - 0.5)
rand_y(y) = y + (rand(0) - 0.5)
plot for [i=0:int(STATS_max)-1] filename \
using (rand_x(timecolumn(1))):(i < $4 ? rand_y($2) : 1/0):3 pointtype 7 linecolor palette notitle
Some other things you must have in mind are:
The stats call must come before set xdata time, because the statistics don't work with time data.
When calculating with time data in the using statement, one needs to use the timecolumn function (as opposed to column or $.. in generic cases). This gives the time as a timestamp (i.e. in seconds).
For that reason you need two different random functions for x and y, because of the very different scalings. Here, I used a 'jitter' of one week (60*60*24*7 seconds) on the time axis.
The result with 4.6.4 is:
Some remarks to your question about learning gnuplot: Try to solve your questions by yourself and then post more concrete questions! Browse through the gnuplot demos to see what is possible, look which feature or plotting style is used, look them up in the documentation, what options/settings are offered? Play around with those demos and try to apply that to your data sets etc. In the end its all about practice (I've been using gnuplot for 12 years...).
I draw a spectrogram with gnuplot version 4.6.
I ensured it is the newest version here:
http://www.gnuplot.info/download.html
Gnuplot is installed from Debian repository.
The plot area and the scale on the right includes strange white lines. They seem to separate the data. On plot area with dense data they look like checkered pattern:
Lines are less visible on the scale but also they are there. There are only horizontal lines on the scale.
I thought it's the case of monitor gamut or something but lines occur also with pdf monochrome.
My code is:
#!/usr/bin/gnuplot
set term pdf
# set style fill noborder # checked with and without this line
set output "../results1/fft.pdf"
set pm3d map
splot "../results1/fft.dat"
As you can read there I tried using option noborder but both with and without the lines exist.
Example data can be:
0 1 3
0 2 3
0 3 4
0 4 2
0 5 2
0 6 3
0 7 4
0 8 3
1 1 3
1 2 2
1 3 4
1 4 2
1 5 2
1 6 3
1 7 4
1 8 4
2 1 2
2 2 4
2 3 4
2 4 3
2 5 2
2 6 4
2 7 2
2 8 2
3 1 2
3 2 3
3 3 3
3 4 4
3 5 2
3 6 2
3 7 2
3 8 2
Do you have any idea how to get rid of this lines?
This has plagued me for some time as well. The best workaround I have is inspired by this post. Basically you can use
plot "datafile" with image
instead of the splot command. There are some subtle differences in how the data is plotted, but this creates a .pdf without those nasty gaps between the colored areas, and a much smaller file.
Note this only really works for data which forms a rectangular grid! If the datafile is in a matrix format (no x or y data except for the number of data points) which for your example would be
3 3 2 2
3 2 4 3
...
(z-value from first row of each block makes the first row, etc.) you can use the command
plot 'datafile' ($1*xincr - x0):($2*yincr - y0):3 matrix with image
The stuff in parens is optional, but allows you to scale the resulting plot to the correct x and y values. (xincr is a gnuplot variable you would have to set for the x-increment in the data, x0 is the x offset, etc.)
If this results in a white gap around the plot, use the plot command once, rescale the axes, and plot again, e.g.
set terminal unknown
plot 'datafile' ($1*xincr - x0):($2*yincr - y0):3 matrix with image
set xr[GPVAL_DATA_X_MIN:GPVAL_DATA_X_MAX]
set yr[GPVAL_DATA_Y_MIN:GPVAL_DATA_Y_MAX]
set output "fft.pdf"
replot
Second answer
I find that this effect is pdf-viewer-dependent. For instance, it shows up in evince under linux but not okular. Depending on your application you could just use a different viewer.
For me, replacing
set pm3d map
with
unset surface; set pm3d at b; set view map
corrects this problem. Tested on gnuplot 4.6 patchlevel 2 and gnuplot 5.4 patchlevel 1.
I can't give much insight as to why, but the manual reveals that
set pm3d map
is a shortcut for
set pm3d at b; set view map; set style data pm3d; set style func pm3d
Simple testing reveals that the problem occurs if either of the "set style" instructions are included. Their removal corrects the problem, but leaves the surface visible - hence "unset surface".
I try to make a plot on gnuplot which has no real range order on x-axis.
--------------------->
1 4 2 20 17 12 10 8
It's therefore not a real function as you would interpret it with math knowledge, but it has some sort of index on its x-axis which has no numbering order and runs from 1-20 but 20 could be the first, or in the middle.. everything may be mixed..
hope you understand what I mean cause I am hoping gnuplot can handle that.
maybe i can write my data file so that point 2 contains the data that should be there on the y-axis and just move the labels around on x-axis?
You could e.g. write a datafile "data" containing such values
1 1.5
4 2
2 3.2
20 2.2
17 0.4
12 4.3
The second column are the "y-values", the first column the labels of the x-axis (xtics)
now try to plot this data with:
plot './data' u 2:xticlabel(1)
is that what you want?
Solution is using xticlabels and add an extra column in the data file.
ie
#xdata ydata label
0 2 1
1 3 14
2 10 0
3 8 20
etc.
command: plot "data.dat" using 1:2:xticlabels(3) with lp"