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.
Related
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
Here is the problem I am having with GNUPLOT: I have data files with two columns each (one for the voltage the other for the current) and each obtained for a certain temperature (which is specified in their name something like iv_300K.dat, iv_290K.dat etc.).
Now what I want is to plot each data file on the same graph and each plot to have a colour based on the file name (I would like to show you a figure I made with Mathematica but it seems that my reputation is too low...)
So lets say I have iv_300K.dat, iv_250K.dat and iv_160K.dat I would like to have three curves coloured first red, second green-ish and third blue, but based on the temperature information in the file name.
I am thinking something similar to what I did in Mathematica:
ColorData["DarkRainbow"][Rescale[T, {160, 350}]]
Where "DarkRainbow" is a colormap and Rescale[x,{min,max}]
gives x rescaled to run from 0 to 1 over the range min to max (according the Mathematica documentation).
So Rescale[250,{160,350}] = 0.473684
At the moment in GNUPLOT I am using the following for testing purposes:
plot for [i=350:160:-10] 'iv_'.i.'.K.dat' using 1:2 with lines title sprintf("".i." K")
but I can't get the colours to map the temperature.
Any help is appreciated!
Use linecolor palette frac to select a color from a palette based on an value in the range [0:1]:
set cbrange [160:350]
set style data lines
plot for [i=350:160:-10] 'iv_'.i.'.K.dat' using 1:2 linecolor palette frac (i-160.0)/(350.0-160.0) title sprintf("%dK", i)
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:
I'm using Gnuplot to make a scatterplot from my data that consists of 5 items:
index, name, x value, y value, color (#12e335)
The color is different for each entry. Is there a way to make the color of my datapoint (x,y) get the color that is listed in the data?
Is it possible in this format for color (#aabb12), or do I need to change to format for gnuplot specific? It is very important that the point color is the same as the color specified in the data, since I use the same colors for a pie-chart later on (not gnuplot).
Any help would be appreciated.
I found the answer myself, after a good hard look.
This line should be at the beginning of your file, right under reset or somewhere around there
rgb(r,g,b) = int(r)*65536 + int(g)*256 + int(b)
And this is your plotting command
plot "output.txt" using 4:5:(rgb($9,$10,$11)) \
with points pt 7 ps 2 lc rgb variable notitle
So basically, you make a new variable rgb with 3 variables, the red, the green and the blue component.
For my problem, i had to add 3 columns to my data files that described my color.
So if my color was #5535cf (i calculate the colors randomly) my rgb value would be (85, 53, 207)
I would then add 3 columns to my output.txt data file with 85, 53 and 207.
These numbers are in column 9, 10 and 11 from my output file, which explains the $9 $10 and $11.
There should be the columnnumbers where your r g and b values are.
If you add lc rgb variable notitle to your plot command, the points should take the color you assigned them in your data-file.
Hope this helps a lot of people!
On the x-axis, I have time as a date %Y-%m-%d. On the y axis I have integers.
Basically, I have a date range for each data point, usually given by a target date and a two week window on either side. I the plot the data point relative to that target window using vertical lines for the low and high ends of the window.
I would like to shade the region between the low and high end.
I tried adding " with filledcurves x1='2000-01-01'"
Thanks
I think you have a few options here. If there are only a few shaded regions that you want to draw, you can use a rectangle (I imagine that this will work -- though I haven't tested it):
set xdata time
set timefmt '%Y-%m-%d'
set object rectangle from first '2000-01-01',graph 0 to first '2001-01-14',graph 1 fc rgb "red" solid back
Another option is that you format your datafile like this:
#date value low-date high-date
2000-01-12 12 2000-01-01 2000-01-26
2000-02-12 12 2000-02-01 2000-02-26
2000-03-12 12 2000-03-01 2000-03-26
Note that there are two blank spaces between each "record" (triple spaced). If your file isn't triple spaced, you can do this easily (in gnuplot) using sed:
plot "< sed 'G;G' datafile.dat" ...
In the special case where low-date and high-date are exactly 3600*24*14 (number of seconds in two weeks) lower/higher than date, you can skip the last two columns and plot it like this:
NPOINTS=3 #Number of points in datafile.
YHIGH=15
set xdata time
set timefmt '%Y-%m-%d'
set style fill solid .5 noborder #somewhat transparent -- see "help fillstyle"
set yrange [0:YHIGH]
plot for [I=0:NPOINTS-1] 'test.dat' i I u 1:(YHIGH):(3600*24*14*2) w boxes,\
for [I=0:NPOINTS-1] 'test.dat' i I u 1:2 w points ls I+1
The first pass draws the rectangles, the second pass draws the points. This only works if the point is in the center of the range, and each range is exactly 3600*24*14 seconds (2 weeks). Note that you'll have to set the number of points and the YHIGH to some value which works for your data.
If the ranges can be skewed -- e.g. the range isn't centered on the point in question, you can probably do something like this:
NPOINTS=3
YHIGH=15
TIMEFMT='%Y-%m-%d'
set xdata time
set timefmt TIMEFMT
set style fill solid .5 noborder #somewhat transparent -- see "help fillstyle"
set yrange [0:YHIGH]
#difference between two times in seconds
boxwidth(s1,s2)=strptime(TIMEFMT,s1)-strptime(TIMEFMT,s2)
#average of two times -- number of seconds since 2000 epoch.
boxmidpoint(s1,s2)=(strptime(TIMEFMT,s1)+strptime(TIMEFMT,s2))/2
set macro #just to make it a little easier to read.
BOXARGS='stringcolumn(4),stringcolumn(3)'
plot for [I=0:NPOINTS-1] 'test.dat' i I u (boxmidpoint(#BOXARGS)):(YHIGH):(boxwidth(#BOXARGS)) w boxes,\
for [I=0:NPOINTS-1] 'test.dat' i I u 1:2 ls I+1