I have to plot several curve on a same graph. I necessarly need to use a for loop to do this. I would like to plot the 2 first curves with lines and the others with points. I am able to plot all the curves with lines or all the curves with points but not to change in the same for loop.
Here is the concerned part of my code:
set style line 1 lw 1 lc rgb "green"
set style line 2 lw 1 lc rgb "purple"
set style line 3 pt 1 ps 1.0 lc rgb "red"
set style line 4 pt 2 ps 1.0 lc rgb "red"
set style line 5 pt 3 ps 1.0 lc rgb "red"
plot for [i=1:words(FILES)] myDataFile(i) u (column(1)):((word(UTAUS_ch,i))) ls i title myTitle(i)
I would like to preface "ls i" with "w l" for the 2 first curves and "ls i" for the others. I tried to use a if statement by replacing "ls i" by "if (i < 2) {w l ls i} else {ls i}" but Gnuplot does not expect to find a if statement at this location.
Can someone help me ?
Thank you,
Martin
As mentioned here you probably cannot switch plotting styles within a plot for loop.
So, either you do two separate loops, one with points and the other with lines or you do one loop with linespoints and define all necessary parameters for points and lines as functions (to keep the plot command readable).
As mentioned here, linewidth 0 is not zero but the thinnest possible line which is typically 1 pixel. To make the line disappear completely you have to use linetype -2.
Code:
### lines and points in the same plot for-loop
reset session
LINECOLORS = "red green blue magenta cyan"
LINEWIDTHS = '1.0 4.0 0.0 0.0 0.0'
POINTTYPES = '0 0 5 7 9'
POINTSIZES = '0 0 1.0 2.0 3.0'
TITLES = 'one two three four five'
myLinecolor(i) = word(LINECOLORS,i)
myLinewidth(i) = real(word(LINEWIDTHS,i))
myPointtype(i) = int(word(POINTTYPES,i))
myPointsize(i) = real(word(POINTSIZES,i))
myLinetype(i) = myLinewidth(i) == 0 ? -2 : 1
myTitle(i) = word(TITLES,i)
set samples 31
set key out
plot for [i=1:words(TITLES)] (sin(0.25*x-i)) w lp pt myPointtype(i) ps myPointsize(i) \
lt myLinetype(i) lw myLinewidth(i) lc rgb myLinecolor(i) title myTitle(i)
### end of code
Result:
Addition:
In order to keep the plot command as short and clear as possible you could also define line styles and use it in the plot for command via ls i, with the same result as above.
...
do for [i=1:words(TITLES)] {
set style line i pt myPointtype(i) ps myPointsize(i) \
lt myLinetype(i) lw myLinewidth(i) lc rgb myLinecolor(i)
}
plot for [i=1:words(TITLES)] (sin(0.25*x-i)) w lp ls i title myTitle(i)
Here a way using a macro:
set style line 1 lw 1 lc rgb "green"
set style line 2 lw 1 lc rgb "purple"
set style line 3 pt 1 ps 1.0 lc rgb "red"
set style line 4 pt 2 ps 1.0 lc rgb "red"
set style line 5 pt 3 ps 1.0 lc rgb "red"
set samp 100
set macro
cmd = ''
do for [i=1:10] {s = i<3? 'w l' : 'ls '.i;
cmd = cmd . '"+" us 1:(sin(x-'.i.'/10.)) '.s.' title "key '.i.'",'}
plot [0:2*pi] #cmd
Related
I am having hard time applying conditional plotting to data with timefmt abscissa using gnuplot 5.0 patchlevel 6.
I am trying to plot the content of an ASCII file consisting in two columns:
2016-12-01 12
2017-01-01 1
2017-02-01 2
2017-03-01 3
2017-04-01 4
2017-05-01 5
2017-06-01 6
so I just issue:
set timefmt "%Y-%m-%d"
set xdata time
p 'file.dat' u 1:2 w l, '' u 1:($1>strptime("%Y-%m-%d","2017-03-01")?$2:10) w p
I expect the plot to look like a line following the second column and a series of dots, following the line for the last three abscissas or marking the value 10 at the previous ones.
Actually, all the points are at 10. Do you have any clue about what is happening? Many thanks in advance.
Use timecolumn.
p 'file.dat' u 1:2 w l, '' u 1:(timecolumn(1, "%Y-%m-%d")>strptime("%Y-%m-%d", "2017-03-01") ? column(2) : (10)) w p
I am trying to generate a Heatmap with gnuplot but with a two distinct information for each entry in the heatmap. While heatmap shows the value as color, I want each block in the heatmap to show textual information as well.
The following script creates half of what I have in mind:
set term postscript eps color solid
set output '1.eps'
set title "Heat Map generated from a file containing Z values only"
unset key
set tic scale 0
set border linewidth 2
set palette rgbformula -7,2,-3
unset cbtics
unset colorbox
unset xtics
set x2tics ("A" 0, "B" 1, "C" 2, "D" 3, "E" 4)
set ytics ("N0" 0, "N1" 1, "N2" 2, "N3" 3, "N4" 4)
set style line 102 lc rgb'#101010' lt 0 lw 4
set grid front ls 102
set datafile separator ","
plot 'matrix.txt' matrix with image, "" matrix using 1:2:(sprintf('%.2f', $3)) with labels font ',12' offset 0,1.2
set datafile separator
The data file, matrix.txt contains the following information:
7 B, 5 B, 4 D, 3 B, 1 D
2 B, 2 A, 2 D, 0 C, 0 A
3 B, 0 A, 0 E, 0 E, 1 C
4 C, 0 A, 0 B, 0 E, 2 C
5 D, 0 A, 1 A, 2 A, 4 A
The following graph can be resulted from the script:
I want to be able to add the textual information in each entry as second part of the matrix entries (under the grid line).
I was wondering if you guys have any suggestions on how.
Thanks
Seems like you cannot use stringcolumn (or strcol) together with matrix to get the complete string contained in the respective matrix elements. As workaround you must iterate over all columns and plot each of them separately with labels:
set title "Heat Map generated from a file containing Z values only"
unset key
set tic scale 0
set border linewidth 2
set palette rgbformula -7,2,-3
unset cbtics
unset colorbox
unset xtics
set x2tics ("A" 0, "B" 1, "C" 2, "D" 3, "E" 4)
set ytics ("N0" 0, "N1" 1, "N2" 2, "N3" 3, "N4" 4)
set style line 102 lc rgb'#101010' lt 0 lw 4
set grid front ls 102
set datafile separator ","
plot 'matrix.txt' matrix with image, \
for [i=1:5] '' using 0:(i-1):i with labels font ',12' offset 0,1.2
I have data showing a change over time, and I have used Gnuplot 4.6 to generate the following plot:
Here, I have manually defined eleven line styles to change the color gradually from red (#ff0000) to dark red (#5f0000) as `time' progresses. Here was my input:
# svg
set terminal svg size 600,600 fname 'CMU Sans Serif' fsize '10'
set output 'plot.svg'
# color definitions
set style line 1 lc rgb '#ff0000' lt 1 lw 2 pt 7 # starting light red
set style line 2 lc rgb '#ef0000' lt 1 lw 2 pt 7
set style line 3 lc rgb '#df0000' lt 1 lw 2 pt 7
set style line 4 lc rgb '#cf0000' lt 1 lw 2 pt 7
set style line 5 lc rgb '#bf0000' lt 1 lw 2 pt 7
set style line 6 lc rgb '#af0000' lt 1 lw 2 pt 7
set style line 7 lc rgb '#9f0000' lt 1 lw 2 pt 7
set style line 8 lc rgb '#8f0000' lt 1 lw 2 pt 7
set style line 9 lc rgb '#7f0000' lt 1 lw 2 pt 7
set style line 10 lc rgb '#6f0000' lt 1 lw 2 pt 7
set style line 11 lc rgb '#5f0000' lt 1 lw 2 pt 7
# visual elements
unset key
set xlabel 'x Axis'
set ylabel 'y Axis'
# plot data
plot for [n=2:11] 'data.dat' using 1:n with lines ls (n-1)
Is there a simpler way to get Gnuplot to gradually change the color as it plots multiple lines? I would ideally like to have a single script that can handle an arbitrary number of color gradations depending on the amount of data from the `data.dat' file.
You can e.g. use a function which calculates the colors depending on the iteration counter
# values r, g, b, x must be in the range [0:1]
rgb(r,g,b) = (255*r*256**2 + 255*g*256 + 255*b)
grad(x) = rgb(1 - x*0.7)
set style data lines
plot for [n=2:11] 'data.dat' using 1:2 lc rgb grad((n-2)/9.0)
Alternatively you can define a gradient and select a fractional position for each line
set palette defined (0 '#5f0000', 1 '#ff0000')
set style data lines
plot for [n=2:11] 'data.dat' using 1:2 lc palette frac (n-2)/9.0
let's assume I have two files formatted like this:
x --- y
0 --- 2
1 --- 2.4
2 --- 3.6
which differ for the values of y.
is there a way to plot a single graph that is, for every x, the maximum value of y between the two files?
Dunno if explained my self sufficiently well.
I was trying with conditional sentences but I couldn't find any expression that let me search in 2 different files
There is no way to combine two files or more in a single plot with gnuplot only. You must use an external tool to do this, e.g. the command line utility paste:
max(x, y) = (x > y ? x : y)
plot '< paste fileA.txt fileB.txt' using 1:(max($2, $4))
The y values are contained in the second and fourth columns.
This next version uses a python script with numpy to concatenate the files, but any other scripting language would also do:
"""paste.py: merge lines of two files."""
import numpy as np
import sys
if (len(sys.argv) < 3):
raise RuntimeError('Need two files')
A = np.loadtxt(sys.argv[1])
B = np.loadtxt(sys.argv[2])
np.savetxt(sys.stdout, np.c_[A, B], delimiter='\t')
To plot, use:
max(x, y) = (x > y ? x : y)
plot '< python paste.py fileA.txt fileB.txt' using 1:(max($2, $4))
Just for the records, there is a way with gnuplot only to get the maximum out of two files.
For sure, it's probably more efficient to use Linux tools or on Windows install, e.g. CoreUtils from GnuWin, but with gnuplot-only you are surely platform independent without extra installations.
Assumption: both files have same number of lines and identical x-values
Edit: simplified code which works for all gnuplot versions>=4.6.0 and faster version for gnuplot>=5.2.0 using an array.
The simple "trick" is to write the y value of one file into a single string and address them via word(). For small data this is ok, but for larger data (>10'000 lines) it might get slow because apparently it runs with something like O(N^2). Just to get an idea (on my system): 1'000 lines take 0.4 seconds, 10'000 lines take 13 seconds and 20'000 lines already take 45 seconds.
As comparison, the array-solution for gnuplot>=5.2.0 just takes about 3 seconds for 10'000 lines.
Data:
SO19079146_1.dat
1 1.1
2 2.1
4 1.5
6 1.3
7 0.2
8 1.5
9 2.1
SO19079146_2.dat
1 2.1
2 2.5
4 1.5
6 0.3
7 0.7
8 1.0
9 1.4
Script 1: (works for gnuplot>=4.6.0, March 2012)
### plot maximum from two files
reset
FILE1 = 'SO19079146_1.dat'
FILE2 = 'SO19079146_2.dat'
data2 = ''
stats FILE2 u (data2=data2.' '.sprintf("%g",$2)) nooutput
set offset 1,1,1,1
max(col) = (i=int(column(0)+1), y1=column(col), y2=real(word(data2,i)), y1>y2 ? y1 : y2)
plot FILE1 u 1:(max(2)) w lp pt 7 lw 8 lc rgb "grey" ti "Max", \
'' u 1:2 w lp pt 7 lc rgb "red" ti "Data1", \
FILE2 u 1:2 w lp pt 7 lc rgb "blue" ti "Data2"
### end of script
Script 2: (works for gnuplot>=5.2.0, Sept. 2017)
### find the maximum out of two files/datablocks (gnuplot>=5.2.0)
reset session
FILE1 = 'SO/SO19079146_1.dat'
FILE2 = 'SO/SO19079146_2.dat'
stats FILE1 u 0 nooutput
array A[STATS_records]
stats FILE2 u (i=int($0+1), A[i]=$2) nooutput
set offset 1,1,1,1
max(col) = (i=int(column(0)+1), y1=column(col), y2=A[i], y1>y2 ? y1 : y2)
plot FILE1 u 1:(max(2)) w lp pt 7 lw 8 lc "grey" ti "Max", \
'' u 1:2 w lp pt 7 lc "red" ti "Data1", \
FILE2 u 1:2 w lp pt 7 lc "blue" ti "Data2"
### end of script
Result: (identical for all above versions)
I am using gnuplot 4.4 patchlevel 4 on Mac OS X v10.6.8. I'm running a gnuplot script, a simplified version of which is this: (file1, file2,...etc are specified in the terminal before running the script)
reset
set term aqua enhanced font "Times-Roman, 18"
set term aqua dashed
plot file1 u 3:10 w lines lt 1 linecolor rgb "#FF0000",\
file2 u 3:10 w lines lt 1 linecolor rgb "#00FF00",\
file3 u 3:10 w lines lt 1 linecolor rgb "#0000FF",\
file4 u 3:10 w lines lt 1 linecolor rgb "#FF00FF",\
file5 u 3:10 w lines lt 1 linecolor rgb "#00FFFF",\
file6 u 3:10 w lines lt 2 linecolor rgb "#FF0000",\
file7 u 3:10 w lines lt 2 linecolor rgb "#00FF00",\
file8 u 3:10 w lines lt 2 linecolor rgb "#0000FF",\
file9 u 3:10 w lines lt 2 linecolor rgb "#FF00FF",\
file10 u 3:10 w lines lt 2 linecolor rgb "#00FFFF"
files 1-5 are one data set and files 6-10 are another. I would like files 1 through 5 to be plotted with solid lines and files 6 through 10 to be plotted with dashed lines. Is there any way to do this in aqua terminal? According to the built-in help, "lines can be drawn either solid or dashed". I've looked at multiple faqs and docs but the consensus seems to be that it is really difficult or impossible to do? Additionally, does anyone know of any comprehensive documentation on the aqua terminal or on gnuplot commands in general?
Edit: To plot files 6-10 I have been using lw 6 to distinguish them from the 1-5 since I couldn't get dashed lines to work. Would the script above as I have it do this correctly? In other words, is the script doing what I think it is doing? (plotting 1-5 solid lines and 6-8 thicker lines?) I ask because in an attempt to make dashed lines, I replace "lw 6" with "lt 2". This however results in file5 being plotted with dashed lines which is just weird.
Edit 2: I attached my terminal test graphic and there doesn't seem to be any mention of dashed lines?
Edit 3: Updated script to reflect changes made.
Edit 4: Graphic is now of set term aqua enhanced font "Times-Roman, 18" dashed; test
It's not too bad at all actually (at least for me on OS-X 10.5.8 with gnuplot 4.2. I stopped building aquaterm in my newer versions of gnuplot as I don't like that terminal) In the aqua terminal, linetype 1 is solid and linetype 2 is dashed.
set term aqua enhanced font "Times-Roman, 18" dashed
plot sin(x) w lines lt 1 lc rgb "blue", cos(x) w lines lt 2 lc rgb "purple"
To see the linetypes that your version of gnuplot will use for a particular terminal, you can use the test command after setting the terminal (and output if the terminal needs it).
A suggestion for how your code should look:
reset
set term aqua enhanced font "Times-Roman, 18" dashed
plot file1 u 3:10 w lines lt 1 linecolor rgb "#FF0000",\
file2 u 3:10 w lines lt 1 linecolor rgb "#00FF00",\
file3 u 3:10 w lines lt 1 linecolor rgb "#0000FF",\
file4 u 3:10 w lines lt 1 linecolor rgb "#FF00FF",\
file5 u 3:10 w lines lt 1 linecolor rgb "#00FFFF",\
file6 u 3:10 w lines lt 2 linecolor rgb "#FF0000",\
file7 u 3:10 w lines lt 2 linecolor rgb "#00FF00",\
file8 u 3:10 w lines lt 2 linecolor rgb "#0000FF",\
file9 u 3:10 w lines lt 2 linecolor rgb "#FF00FF",\
file10 u 3:10 w lines lt 2 linecolor rgb "#00FFFF"
EDIT
I just looked on a friend's computer. for her (gnuplot 4.4.4, os-X 10.6?) linetype 8 was the first dashed linetype (highlighting the usefulness of the test command).