Read Colour Value from Datafile in Gnuplot - gnuplot

I am trying to plot vectors with different colours. The colour value is stored as a third column in the data file.
For example, let us say the datafile is "a.txt" contains
0.603358 2.022173 1
1.08929 2.039982 2
1.588976 2.040512 3
The typical plot is
plot 'a.txt' using 1:1:($2-$1):(0) notitle with vectors heads size screen 0.008,90 lc 2
The question is that how the "lc" takes the third column value?

Use linecolor variable, it gets color from the last mentioned column.
plot 'a.txt' using 1:1:($2-$1):(0):3 notitle with vectors heads size screen 0.008,90 lc variable

Related

How to remove line between "jumping" values, in gnuplot?

I would like to draw a line with plots that contain "jumping" values.
Here is an example: when we have plots of sin(x) for several cycles and plot it, unrealistic line will appear that go across from right to left (as shown in following figure).
One idea to avoid this might be using with linespoints (link), but I want to draw it without revising the original data file.
Do we have simple and robust solution for this problem?
Assuming that you are plotting a function, that is, for each x value there exists one and only one corresponding y value, the easiest way to achieve what you want is to use the smooth unique option. This smoothing routine will make the data monotonic in x, then plot it. When several y values exist for the same x value, the average will be used.
Example:
Data file:
0.5 0.5
1.0 1.5
1.5 0.5
0.5 0.5
Plotting without smoothing:
set xrange [0:2]
set yrange [0:2]
plot "data" w l
With smoothing:
plot "data" smooth unique
Edit: points are lost if this solution is used, so I suggest to improve my answer.
Here can be applied "conditional plotting". Suppose we have a file like this:
1 2
2 5
3 3
1 2
2 5
3 3
i.e. there is a backline between 3rd and 4th point.
plot "tmp.dat" u 1:2
Find minimum x value:
stats "tmp.dat" u 1:2
prev=STATS_min_x
Or find first x value:
prev=system("awk 'FNR == 1 {print $1}' tmp.dat")
Plot the line if current x value is greater than previous, or don't plot if it's less:
plot "tmp.dat" u ($0==0? prev:($1>prev? $1:1/0), prev=$1):2 w l
OK, it's not impossible, but the following is a ghastly hack. I really advise you add an empty line in your dataset at the breaks.
$dat << EOD
1 1
2 2
3 3
1 5
2 6
3 7
1 8
2 9
3 10
EOD
plot for [i=0:3] $dat us \
($0==0?j=0:j=j,llx=lx,lx=$1,llx>lx?j=j+1:j=j,i==j?$1:NaN):2 w lp notit
This plots your dataset three times (acually four, there is a small error in there. I guess i have to initialise all variables), counts how often the abscissa values "jump", and only plots datapoints if this counter j is equal to the plot counter i.
Check the help on the serial evaluation operator "a, b" and the ternary operator "a?b:c"
If you have data in a repetitive x-range where the corresponding y-values do not change, then #Miguel's smooth unique solution is certainly the easiest.
In a more general case, what if the x-range is repetitive but y-values are changing, e.g. like a noisy sin(x)?
Then compare two consecutive x-values x0 and x1, if x0>x1 then you have a "jump" and make the linecolor fully transparent, i.e. invisible, e.g. 0xff123456 (scheme 0xaarrggbb, check help colorspec). The same "trick" can be used when you want to interrupt a dataline which has a certain forward "jump" (see https://stackoverflow.com/a/72535613/7295599).
Minimal solution:
plot x1=NaN $Data u 1:2:(x0=x1,x1=$1,x0>x1?0xff123456:0x0000ff) w l lc rgb var
Script:
### plot "folded" data without connecting lines
reset session
# create some test data
set table $Data
plot [0:2*pi] for [i=1:4] '+' u 1:(sin(x)+rand(0)*0.5) w table
unset table
set xrange[0:2*pi]
set key noautotitle
set multiplot layout 1,2
plot $Data u 1:2 w l lc "red" ti "data as is"
plot x1=NaN $Data u 1:2:(x0=x1,x1=$1,x0>x1?0xff123456:0x0000ff) \
w l lc rgb var ti "\n\n\"Jumps\" removed\nwithout changing\ninput data"
unset multiplot
### end of script
Result:

How to plot data with lines like "<text> <datetime>", with gnuplot?

My data is a typical CSV-like text where each line consists of two columns where the first is text and the second a unix timestamp, as follows:
Mom 1441008169
Dad 1442516527
Ken 1441783871
...
<text> <unix-timestamp>
I thought I could arrange the data along a timeline, drawing dots/shapes of color corresponding to the text in the line, at a point along the x axis corresponding to the timestamp. At best I got gnuplot to tell me:
line 0: Need using spec for y time data
when I tell it to:
set ydata time
set timefmt "%s"
plot "-"
<data>
EOF
I want to render a plot using dots, or diamonds or shapes with color corresponding to the text string in first column. In other words, if my text values fall within the set {"Mom", "Dad", "Ken"}, then gnuplot should draw these shapes corresponding to "Mom" in red, "Dad" in green, and "Ken" in blue, or something like that, at points corresponding to their respective timestamps along the x axis.
The challenge for me is to have gnuplot distinguish between the text strings. The data can be thought of as, for instance, incoming calls from a person where the timestamp indicates date and time for the call and text represents the person calling. I thought representing these data as plotted dots/orbs/diamonds/whatever of different color along a time line would be a good idea, visually.
How would I achieve that? I can, optionally, generate some sort of identifier table where the unique text strings are each equated to a unique sequential generated ID, if that helps gnuplot.
I guess what you want is something like this
The x-axis spans the time interval which is specified by your data file (2nd column). Each name (Ken, Mom, Dad) is represented by a different point type (pt) and a specific colour (lc rgb 'color').
You can generate this plot by the following commands (assuming your data file's name is 'test'):
set xdata time
set timefmt "%s"
set format x "%d/%m/%y"
set xtics rotate
unset ytics
set yrange[0:2]
plot 'test' u ($2):(stringcolumn(1) eq "Ken" ? 1 :1/0) w p pt 5 ps 1.5 lc rgb 'blue' t 'Ken',\
'' u ($2):(stringcolumn(1) eq "Dad" ? 1 :1/0) w p pt 7 ps 1.5 lc rgb 'red' t 'Dad',\
'' u ($2):(stringcolumn(1) eq "Mom" ? 1 :1/0) w p pt 3 ps 1.5 lc rgb 'green' t 'Mom'
You can use different point types by assigning different numbers to pt. ps specifies the point size.
Another representation I came up with is the following:
You can generate it with:
plot 'test' u ($2):(1):(stringcolumn(1)) with labels t '',\
'' u ($2):(0.95) with impulses t ''
I hope this answers your question, and it is what you were looking for.

Gnuplot histogram gap does nothing

I have a gnuplot script which plots a histogram. I used the following syntax:
set style data histogram
set style histogram cluster gap 2
set style fill solid
set logscale y
rgb(r,g,b) = int(r)*65536 + int(g)*256 + int(b)
plot 'histogram_data' using (column(0)):2:(0.5):(rgb($3,$4,$5)):xticlabels(1) w boxes notitle lc rgb variable
What the last line does is: using column 1 as x labels, column 2 as the height of the histogram bars, 0.5 as box width, and columns 3, 4 and 5 as the rgb values to colour the bars.
Now, the problem is that modifying the gap parameter in line 2 does not change in any way the spacing between bars, even though as far as I understand that is the correct way to adjust such spacing. I am using gnuplot 4.6 patchlevel 4.
I found a way to do this with boxes, though I do not consider it very clean:
plot 'histogram_data' u (column(0)*2+1):2 w boxes notitle lc rgb 'white',\
'histogram_data' u (column(0)*2):2:(rgb($3,$4,$5)):xticlabels(1) w boxes notitle lc rgb variable;
This command is plotting all the data of the main plot on even slots and a white box on odd slots. So the first line in the plot command is plotting the gaps between every box of the plot (the width of these gaps can be specified using the boxwidth property I think but I haven't tested this), while the second line is drawing the actual plot.
I could not find a way to do this with the histogram plotting style, keeping the variable colours specified in the data file.

Is there a way to put a label for the last entry in gnuplot?

I want to use gnuplot for real time plotting (Data gets appended to file which I use for plotting and I use replot for real time plotting). I also want to put a label for the latest entry which is plotted. So as to get a idea what is the latest value. Is there a way to do this?
If you are on a unixoid system, you can use tail to extract the last line from the file and plot it separately in whatever way you desire. To give a simple example:
plot\
"data.dat" w l,\
"< tail -n 1 data.dat" u 1:2:2 w labels notitle
This will plot the whole of data.dat with lines and the last point with labels, with the label depicting the value.
There is no need to use the Linux command tail, you can simply do it with gnuplot-only, hence platform-independently.
The principle: while plotting the data, you assign the values of column 1 and 2 to variables x0 and y0, respectively.
After the first plot command, x0 and y0 will contain the last values.
With this, you don't have to load the file a second time for extracting the last values.
For the label plotting, use these values and print the label with a sprintf() expression (check help sprintf).
The construct '+' u ... every ::0::0 is just one way of many ways to plot a single data point.
Data: SO28152083.dat
1 5.1
2 2.2
3 3.3
4 1.4
5 4.5
Script: (works with gnuplot 4.4.0, March 2010 or even with earlier versions)
### plot last value as label
reset
FILE = "SO28152083.dat"
set key noautotitle
set offsets 0.5,0.5,1,1
plot FILE u (x0=$1):(y0=$2) w lp pt 7 lc rgb "red" ti "data", \
'+' u (x0):(y0):(sprintf("%g",y0)) every ::0::0 w labels offset 0,1
### end of script
Result:

Gnuplot read line style from data file column

I'd like to draw an impulse graph from a text file that looks like this:
II 5 0 0 288.40 1.3033e+14
II 6 0 0 289.60 1.5621e+14
II 1 4 0 302.70 3.0084e+13
II 2 4 0 303.40 4.0230e+13
II 1 5 1 304.40 3.4089e+13
The plot conceptually should be plot "datafile.dat" using 5:6 w impulses ls $2.
Basically, given a previously defined set of line styles, I'd like to input the line style number from column 2 for every couple of plotted points from column 5 and 6.
Also I'd like to create a text box, for every plotted point, taking strings from the first four columns.
Does somebody know if that's possible?
To use the data from column two as line style use set style increment user and linecolor variable:
set style increment user
plot "datafile.dat" using 5:6:2 with impulses lc var
In order to place a label, use the labels plotting style:
plot "datafile.dat" using 5:6:1 with labels offset 0,1
Putting everything together, you have:
set style increment user
set for [i=1:6] style line i lt i
set yrange [0:*]
set offsets 0,0,graph 0.1,0
plot "datafile.dat" using 5:6:2 with impulses lc var, "" using 5:6:1 with labels offset 0,1
The result with 4.6.3 is:
Thanks for the helpful answer above. It almost solved my problem
I'm actually trying to use a column from my data file to specify a linestyle (dot, squares,triangles, whatever as long as it's user-defined), and not a linecolor. Is there any way to do that?
This line works : I get points with different colors (specified in column 4), but the point style is the same.
plot "$file" u 1:2:4 w p notitle lc var, "" using 1:2:3 with labels offset 0,1 notitle
Replacing lc with ls after defining my own styles doesn't work (ls can't have variable as an option)
I can live without different linestyles, but it would be much prettier.
You only have to replace the lineset for [i=1:6] style line i lt i for set for [i=1:6] style line i lt i pt %, Where % can be any type of point you want

Resources