The data input from stdin fails for the second time as follows, how can I solve this problem?
plot '-' w l
0 0
5 0
e
replot '-' w l
^
unexpected or unrecognized token
replot after data input from stdin also fails
plot '-' w l
0 0
5 0
e
replot sin(x)
^
unexpected or unrecognized token
The following code works, so I don't know what's the problem.
plot sin(x)
replot '-' w l
0 0
5 0
e
I know plot '-' w l, '-' w l will draw multiple lines. But I'm using gnuplot from the program and I don't have all data to plot in advance. So I can't use this method.
I think I can solve this problem by writing the results of the process to a file, but can't I do that from stdin? I want to plot incrementally.
Thanks.
The recommended way to do this is by using a datablock rather than the pseudo-file '-'. Here is what the input stream to gnuplot should look like.
# Begin input
$DATA1 << EOD
1 2
3 4
EOD
plot $DATA1 with lines
$DATA2 << EOD
5 6
7 8
EOD
replot $DATA2
# or I would actually prefer
plot $DATA1 with lines, $DATA2 with lines
Related
In gnuplot, we can set object polygon to draw a polygon, including triangles, given its coordinates.
But how to do draw a set of triangles whose coordinates are stored in a file where each line is in the format <x1> <y1> <x2> <y2> <x3> <y3>?
As for rectrangles/circles, this task can be done using plot and with boxxy/with circles options, but there is no with triangles option in gnuplot.
A possible solution is to use with vectors by drawing each edge, but it is a bit complicated and this method does not support color filling.
I cannot think of a way to do this in one step; the data format does not match any of gnuplot's plotting styles.
One approach is to transform the data via a temporary file. Here is an example that works in version 5.2 and newer. If you are using a newer gnuplot then you could substitute with polygons for with filledcurves closed.
$DATA << EOD
1 1 2 2 3 1
11 11 14 14 17 11
21 21 22 22 23 21
15 5 16 6 17 5
6 6 7 7 8 6
EOD
set table "temp.dat"
plot $DATA using (sprintf("%g %g\n %g %g\n %g %g\n \n",$1,$2,$3,$4,$5,$6)) with table
unset table
unset key
set style fill solid noborder
plot "temp.dat" using 1:2 with filledcurves closed fillcolor "forest-green"
Note: I was originally going to show use of a temporary datablock rather than an intermediate temporary file, but it this doesn't work because the formatted output from with table does not translate the newline characters \n into empty datablock lines.
Edit (show variable color)
The extra data field containing a RGB color must be present in every input line of the reformatted data, but only the value from the first vertex of each polygon is used. The sprintf format in this example has been modified to reproduce the color (NB: hexadecimal integer value) from the original data file accordingly, with zeros for the dummy values in the remaining polygon vertices.
$DATA << EOD
1 1 2 2 3 1 0x00ffff
11 11 14 14 17 11 0x191970
21 21 22 22 23 21 0x2e8b57
15 5 16 6 17 5 0xffc020
6 6 7 7 8 6 0x8b000
EOD
set table "temp.dat"
plot $DATA using (sprintf("%g %g 0x%x\n %g %g 0\n %g %g 0\n \n",$1,$2,int($7),$3,$4,$5,$6)) with table
unset table
unset key
set style fill solid noborder
plot "temp.dat" using 1:2:3 with filledcurves closed fillcolor rgb variable
My suggestion would have been the same as #Ethan's. Therefore, here is an alternative approach using set object polygon.
It also requires gnuplot>=5.2 since it uses indexing of datablock lines. Hence, the data should already be in a datablock without empty or commented lines. But how to get a file into a datablock?
Either something like:
set table $Data
plot FILE u 1:2:3:4:5:6:7 w table
unset table
or alternatively see here: gnuplot: load datafile 1:1 into datablock
Script:
### draw some colored triangles from a datablock
reset session
$Data <<EOD
0 0 2 1 1 2 0xff0000
5 1 3 2 4 4 0x00ff00
3 3 2 5 1 4 0x0000ff
EOD
vx(n,t) = word($Data[n],t*2-1) # vertex x-coordinate
vy(n,t) = word($Data[n],t*2) # vertex y-coordinate
color(n) = word($Data[n],7) # triangle color
set linetype 1 lc rgb "black"
do for [n=1:|$Data|] {
set obj n polygon from vx(n,1),vy(n,1) to vx(n,2),vy(n,2) to vx(n,3),vy(n,3) to vx(n,1),vy(n,1)
set obj n fc rgb color(n) fs solid 0.5 border lt 1 lw 3
}
set size square
set xrange[0:5]
set yrange[0:5]
plot NaN notitle # or plot something else
### end of script
Result:
Addition:
Alternatively, similar to Ethan's solution, plotting triangles instead of drawing triangles, but without using a temporary file on disk (but a datablock). The result is identical to the graph above. I haven't tested whether drawing or plotting is faster and/or more efficient if you want to draw/plot thousands of triangles.
Script:
### plot some colored triangles from a datablock
reset session
$Data <<EOD
0 0 2 1 1 2 0xff0000
5 1 3 2 4 4 0x00ff00
3 3 2 5 1 4 0x0000ff
EOD
vx(n,t) = word($Data[n],t*2-1) # vertex x-coordinate
vy(n,t) = word($Data[n],t*2) # vertex y-coordinate
color(n) = word($Data[n],7) # triangle color
set print $Triangles
do for [n=1:|$Data|] {
print sprintf("%s %s %s\n%s %s 0\n%s %s 0\n%s %s 0\n\n", \
vx(n,1),vy(n,1),color(n), vx(n,2),vy(n,2), vx(n,3),vy(n,3), vx(n,1),vy(n,1))
}
set print
set size square
set xrange[0:5]
set yrange[0:5]
set linetype 1 lc rgb "black" lw 3
set style fill solid 0.5
plot $Triangles u 1:2:3 w filledcurves lc rgb var notitle
### end of script
I am trying to draw a rudimentary line segment from (0,0) to (0,1). I already have an input file, but I want to add a line to it.
I have read through Line plot in GnuPlot where line width is a third column in my data file? and Plot line segments from a datafile with gnuplot among many other examples. Everyone is doing something much more complex than what I want, I only want the line segment added to my GNUPlot script.
I normally enter the data in to GNUPlot thus:
$DATA << EOD
.... other data
EOD
$LS << EOL
0 0
0 1
EOL
plot $DATA using 1:2:3 with points
plot $LS with lines
but this doesn't work, nor does
plot $LS using 1:2 with lines
How can I plot this simple line segment from (0,0) to (0,1)?
What does "doesn't work" mean? You don't even show the resulting graph. By the way what do you use the 3rd column for?
Your first example will make a plot only with your data and then a new plot with only the line segment.
And in your second example, the line from 0,0 to 0,1 in your plot is identical with the y-axis and therefore hard to see as long as the xrange starts from 0. You can easily check this, e.g. if you set the color to red or linewidth to 3 , e.g.
plot $LS u 1:2 lc "red" lw 3
You also can make your line segment "visible" if you set xrange[-0.2:]. Check the following example
Code:
### plotting simple line segments
reset session
$DATA << EOD
0.1 0.2 1
0.3 0.4 2
0.5 0.6 3
0.7 0.5 4
EOD
$LS1 << EOL
0 0
0 1
EOL
$LS2 <<EOL
0 0
1 1
EOL
set xrange [-0.2:]
plot $DATA using 1:2:3 with points pt 7, \
$LS1 u 1:2 with lines, \
$LS2 u 1:2 with lines
### end of code
Result:
You can use headless arrows to plot arbitrary line segments.
set xrange [0:1]
set yrange [0:1]
set arrow 1 from 0,0 to 0,1 nohead lw 3 lc 2
set arrow 2 from 0,0 to 1,1 nohead lw 2
plot NaN t''
Ive this script in gnuplot and I want to print multiple plots from 1 dataset. Ive tried this command but it seems that command needs another sama dataset to execute this command correctly. Do you know how to solve it?
plot '-' using 1:2, '=' using 1:3
1 1 5
2 2 5
3 3 5
e
With '-' you would have to enter the same data again. Check help special-filenames.
You better do:
$Data <<EOD
1 1 5
2 2 5
3 3 5
EOD
plot $Data u 1:2, '' u 1:3
I basically want this (first diagram) done with gnuplot. I've searched and found nothing exactly like this. I can do a good heaviside without the little circles at the end and start of the two lines, but I can't seem to get it with the little circles. Actually, the second diagram would be nice to know too. The third too, but I'm not greedy.
Just for the records and completeness... although you can define a function
H(x) = x<0 ? 0 : 1
If you plot
plot H(x) w l
the line will be continuous at zero and of course without points.
So, another suggestion with just two columns x,y and variable pointtype would be the following.
Code:
### Heaviside function
reset session
$Heaviside <<EOD
-2 0
0 0
0 0.5
0 1
2 1
EOD
set yrange [-1:2]
set ytics 1
unset key
set multiplot layout 3,1
plot $Heaviside u 1:2 w l lc 0, \
'' u 1:($0==1||$0==3?$2:NaN):($0==3?7:6) w p pt var lc 0
plot $Heaviside u 1:2 w l lc 0, \
'' u 1:($0==1||$0==2||$0==3?$2:NaN):($0==2?7:6) w p pt var lc 0
set xrange [0:4]
a = 3
plot $Heaviside u ($1+a):2 w l lc 0, \
'' u ($1+a):($0==1||$0==3?$2:NaN):($0==3?7:6) w p pt var lc 0
unset multiplot
### end of code
Result:
Addition:
A variation with shorter and less confusing plot command, but using 4 columns together with variable pointtype. This will give the same result as above.
Code:
### Heaviside function
reset session
$Heaviside <<EOD
-2 0 NaN NaN
0 0 6 6
0 0.5 NaN 7
0 1 7 6
2 1 NaN NaN
EOD
set yrange [-1:2]
set ytics 1
unset key
set multiplot layout 3,1
plot $Heaviside u 1:2 w l lc 0, \
'' u 1:2:3 w p pt var lc 0
plot $Heaviside u 1:2 w l lc 0, \
'' u 1:2:4 w p pt var lc 0
set xrange [0:4]
a = 3
plot $Heaviside u ($1+a):2 w l lc 0, \
'' u ($1+a):2:3 w p pt var lc 0
unset multiplot
### end of code
Addition 2:
In order to finalize the answer, here is an approach to plot functions containing the Heaviside function.
Instead of plotting from a datablock with fixed x-values (as in the two examples above) it uses the current x-range. Note, for example the syntax plot '+' u 1:(sin($1)) is basically identical with plot sin(x).
Apparently, setting the line color via lc rgb -1 does not plot a line, which can be used here to interrupt the line. You may want to increase the samples, e.g. set samples 300 to avoid a gap between the points and the function.
Code:
### plotting Heaviside function and functions containing Heaviside function
# including line interruption and inclusion/exclusion points
reset session
Heaviside(x,a) = x<a ? 0 : 1 # definition of Heaviside function
array Hpoints[2] = [6,7] # array for plotting "Heaviside points"
Hcolor(x) = (x0=x1, x1=x, x0<a && x1>=a ? -1 : 0xff0000) # set color -1 for line interruption
dx(n) = 1e-3*(2*n-1) # small dx to get y-value of points close to break
f(x,a) = 50/(x**2+2)*cos(4*x) * Heaviside(x,a)
unset key
set multiplot layout 2,1
a = 2.0
set yrange[-1:2]
plot x1=NaN '+' u 1:(Heaviside(x,a)):(Hcolor(x)) w l lc rgb var, \
Hpoints u (a):(Heaviside($1,a)):(Hpoints[$0+1]) w p pt var lc rgb Hcolor(NaN)
a= 0
set samples 300
set yrange[-25:35]
plot x1=NaN '+' u 1:(f(x,a)):(Hcolor(x)) w l lc rgb var, \
Hpoints u (a):(f(a+dx($0),a)):(Hpoints[$0+1]) w p pt var lc rgb Hcolor(NaN)
unset multiplot
### end of code
Result:
I created the following datafile (mind the two empty lines):
-2 0 0 1
0 0 2 1
0 0 0 1
and ran the following gnuplot commands:
set yrange [-2:2]
plot "file" using 1:2 with lines,\
"" using 3:4 with lines, \
"" index 1 using 1:2 with points pointtype 6, \
"" index 1 using 3:4 with points pointtype 7
Fix the colours to your liking.
I have x,y values for points in the first 2 colums and a number that indicates the point type (symbol) in the 3. column, in one data file. How do I plot data points with different symbols?
Unfortunately, there isn't a way (AFAIK) to automatically set the point of the plot from a column value using vanilla GNUPLOT.
However, there is a way to get around that by setting a linestyle for each data series, and then plotting the values based on that defined style:
set style line 1 lc rgb 'red' pt 7 #Circle
set style line 2 lc rgb 'blue' pt 5 #Square
Remember that the number after pt is the point-type.
Then, all you have to do is plot (assuming that the data in "data.txt" is ordered ColX ColY Col3):
plot "data.txt" using 1:2 title 'Y Axis' with points ls 1, \
"data.txt" using 1:3 title 'Y Axis' with points ls 2
Try it here using this data (in the section titled "Data" - also note that column 3 "Symbol" is noted used, it's mainly there for illustrative purposes):
# This file is called force.dat
# Force-Deflection data for a beam and a bar
# Deflection Col-Force Symbol
0.000 0 5
0.001 104 5
0.002 202 7
0.003 298 7
And in the Plot Script Heading:
set key inside bottom right
set xlabel 'Deflection (m)'
set ylabel 'Force (kN)'
set title 'Some Data'
set style line 1 lc rgb 'red' pt 7
set style line 2 lc rgb 'blue' pt 5
plot "data.txt" using 1:2 title 'Col-Force' with points ls 1, \
"data.txt" using 1:3 title 'Beam-Force' with points ls 2
The one caveat is of course that you have have to reconfigure your data input source.
REFERENCES:
http://www.gnuplotting.org/plotting-single-points/
http://www.gnuplotting.org/plotting-data/
Here is a possible solution (which is a simple extrapolation from gnuplot conditional plotting with if), that works as long as you don't have tens of different symbols to handle.
Suppose I want to plot 2D points in a coordinate system. I have only two symbols, that I arbitrarily represented with a 0 and a 1 in the last column of my data file :
0 -0.29450470209121704 1.2279523611068726 1
1 -0.4006965458393097 1.0025811195373535 0
2 -0.7109975814819336 0.9022682905197144 1
3 -0.8540692329406738 1.0190201997756958 1
4 -0.5559651851654053 0.7677079439163208 0
5 -1.1831613779067993 1.5692367553710938 0
6 -0.24254602193832397 0.8055955171585083 0
7 -0.3412654995918274 0.6301406025886536 0
8 -0.25005266070365906 0.7788659334182739 1
9 -0.16853423416614532 0.09659398347139359 1
10 0.169997438788414 0.3473801910877228 0
11 -0.5252010226249695 -0.1398928463459015 0
12 -0.17566296458244324 0.09505800902843475 1
To achieve what I want, I just plot my file using conditionals. Using an undefined value like 1/0 results in no plotting of the given point:
# Set styles
REG_PTS = 'pointtype 7 pointsize 1.5 linecolor rgb "purple"'
NET_PTS = 'pointtype 4 pointsize 1.5 linecolor rgb "blue"'
set grid
# Plot each category with its own style
plot "data_file" u 2:($4 == 0 ? $3 : 1/0) title "regular" #REG_PTS, \
"data_file" u 2:($4 == 1 ? $3 : 1/0) title "network" #NET_PTS
Here is the result :
Hope this helps
Variable pointype (pt variable) was introduced (I guess) not until gnuplot 5.2.0 (Sept 2017) (check help points).
Just in retrospective, another (awkward) solution would be the following for those who are still using such early versions.
Data:
1 1.0 4 # empty square
2 2.0 5 # filled square
3 3.0 6 # empty circle
4 4.0 7 # filled circle
5 5.0 8 # empty triangle up
6 6.0 9 # filled triangle down
7 7.0 15 # filled pentagon (cross in gnuplot 4.6 to 5.0)
Script: (works from gnuplot>=4.6.0, March 2012; but not necessary since 5.2.0)
### variable pointtype for gnuplot>=4.6
reset
FILE = 'SO23707979.dat'
set key noautotitle
set offsets 1,1,1,1
set pointsize 4
stats FILE u 0 nooutput
N = STATS_records # get the number of rows
p0=x1=y1=NaN
plot for [n=0:N-1 ] FILE u (x0=x1, x1=$1, x0):(y0=y1, y1=$2, y0):(p0=$3) \
every ::n::n w p pt p0 lc rgb "red", \
FILE u 1:2 every ::N-1::N-1 w p pt p0 lc rgb "red"
### end of script
Result: