plotting "with impulses" using multiple fields from an input file - gnuplot

sample "input file":
x y1(red) y2(blue) y3(green)
10 0.08 0.02 0.90
15 0.03 0.90 0.07
20 0.85 0.10 0.05
My x-axis is 10, 15, 20, or column 1 in the sample input file. Columns 2-4 are my dependent variables, labeled by color. The x-axis is distance; the y-axis is impulse signal.
goal
I would like a graph plotted as "x:y with impulse", or something equivalent. My output would appear like:
x = 10 15 20
green 0.90 0.07 0.05
red 0.08 0.03 0.85
blue 0.02 0.90 0.10
At x = 10, I would see a green line with an intensity of 0.90, overlapped by a red line with an intensity of 0.08, followed by a blue line with intensity 0.02. I can tell at a glance that for x=10, my parameter is 90% green, 8% red, and 2% blue.
For x=15, I would have a blue line with an intensity of 0.90, a green line with an intensity of 0.07, and a red line with intensity 0.03.
and similar for x = 20.
In other words, my goal is to see, for a given x-value, exactly what percentage contributions my three dependent variables have.
problem
Currently, I can do something like
plot "input file" u 1:4 w i lc rgb "green"
replot "input file" u 1:3 w i lc rgb "blue"
replot "input file" u 1:2 w i lc rgb "red"
Unfortunately, the most recent replot will overlap and cover up any previous plots of smaller impulse.
With this approach, my plot would look like:
x = 10 15 20
green 0.90 ---- ----
red 0.08 0.03 0.85
blue ---- 0.90 ----
I would only see green at x = 10, and blue only at x = 15. Because red is replotted last, it overlaps and covers the other colors due to having a greater intensity. I can see red perfectly at all three x-values, but I lose green and blue.
Is there maybe a way to tell replot to not overshadow previous plots? Or an alternative approach to replot to achieve the goal stated above?
summary
I am trying to plot a multi-field input at each point x, while preserving the original legend label in my key for each column.
In my actual case, I have anywhere from 8-40 fields, across a few hundred x values, so I can't simply input manually which columns I'd like where.
Any assistance is greatly appreciated. I am open to any solutions, even a different software if gnuplot cannot do this.

set linetype 1 lc "green"
set linetype 2 lc "red"
set linetype 3 lc "blue"
unset key
set yrange [0:1]
set style data histogram
set style histogram cluster gap 3
set style fill solid
plot for [col=2:4] 'inputfile' using col:xticlabel(1)

Related

Colour points in X,Y scatter based on value of continuous data in another column

My question is similar to this one:
vary point color based on column value for multiple data blocks gnuplot
Except there was not an explanation given above for the syntax used and what it meant..
The data looks like this - columns separated by a comma and enter separates rows:
0, 0F_0F_0F_0F_0F, 0_0_0_0_0_0_0_0_0_0, 1_0_0_0_0_0_0_0_0_0
4.046025985, 0F_2Fo_0F_2Fo_0F, 0_0_1_0_0_0_0_0_1_0, 1_1_0_0_0_0_1_0_0_0
2.941144083, 0F_0F_0F_0F_0F, 0_0_1_0_0_1_0_0_0_1, 1_0_0_0_1_0_0_0_0_0
1.836301245, 0F_0F_0F_2Fo_0F, 0_0_0_0_0_0_0_0_0_0, 1_0_0_0_0_0_0_0_0_0
0.90317579, 0F_0F_0F_2Fo_0F, 0_0_0_1_0_0_0_1_0_0, 1_0_1_0_0_1_0_0_1_0
3.826663156, 0F_0F_0F_0F_0F, 0_1_0_0_1_0_1_0_0_1, 1_0_1_0_0_0_0_0_0_0
In my datafile, there are 100 individual rows, where column 1 is to be used for the colour palette and columns 2-4 are labels for X,Y axes on two different plots
What I want is an X,Y scatter of columns 3 and 4, with column 1 used to colour each point on the plot.
Here is my script attempt:
set title "K and W Occupancy \n KcsA, Replica 0, 0 mV "
set xlabel "POT" font ",18"
set ylabel "Water" font ",18"
set cblabel "Free energy (kT)" font ",18"
set xtics rotate by -45
set xtics out font ", 13" nomirror
set ytics out font ", 13" nomirror
set pointsize 0.4
set xrange [0:100]
iset yrange [0:100]
set cbrange [0:10]
# MATLAB jet color pallete --> from https://github.com/Gnuplotting/gnuplot-palettes/blob/master/jet.pal
# palette
set palette defined (0 0.0 0.0 0.5, \
1 0.0 0.0 1.0, \
2 0.0 0.5 1.0, \
3 0.0 1.0 1.0, \
4 0.5 1.0 0.5, \
5 1.0 1.0 0.0, \
6 1.0 0.5 0.0, \
7 1.0 0.0 0.0, \
8 0.5 0.0 0.0 )
splot '$filename' using 3:4:($1 <= 10 ? 0 : 1) w p pointtype 5 pointsize 1 palette linewidth 10
I do not really know what this means:
($1 <= 10 ? 0 : 1)
Why does the script plot a 3D graph with the data incorrectly placed?
Was expected a 2D plot with unique entries along the X and Y axes, with each point coloured along a colour scale..
The attempt described above results in a 3D plot and the points are incorrect.
Multiple answers to similar questions I have read do not explain what each term in the gnuplot script means, including:
Plotting style based on an entry in a data-file
gnuplot splot colors based on a fourth column of the data file
vary point color based on column value for multiple data blocks gnuplot
We don't have your data (if possible please always add minimized data) and we don't see your graph output.
I do not really know what this means: ($1 <= 10 ? 0 : 1)
This is the ternary operator. Check help ternary. If the value in column 1 ($1) is smaller or equal to 10 return 0, and 1 otherwise.
Why does the script plot a 3D graph with the data incorrectly placed?
Because you told gnuplot so. Mind the difference splot and plot. Check help splot and help plot. splot requires x,y,z input and your z is ($1 <= 10 ? 0 : 1)
So, without being able to test your case, your command probably should be something like this:
plot '$filename' u 3:4:1 w p pt 5 ps 1 lc palette
Addition:
If I understood your question correctly, I guess there is no off-the-self plotting style for this.
You need to:
create lists of unique elements (by (mis-)using stats, check help stats) for x and for y (in your case column 3 and 4). The list will be in the order of occurrence in the datafile. Unfortunately, gnuplot does not offer an internal alphanumerical sort of a list. If you want it sorted you need to either use external tools or a cumbersome gnuplot-only workaround.
define a function by (mis-)using sum (check help sum) which determines the index of a given item and use this index either as x- or y-coordinate
Script:
### scatter plot with x,y strings
reset session
$Data <<EOD
0.00, 0F_0F_0F, 0_0_0_0, 0_0_0_0
0.43, 0F_0F_0F, 0_1_1_1, 1_0_1_1
0.64, 0F_0F_0F, 0_1_1_1, 1_1_0_0
0.73, 0F_0F_0F, 0_1_1_1, 0_1_1_1
0.29, 0F_0F_0F, 0_1_0_1, 1_0_1_1
0.34, 0F_0F_0F, 0_1_0_1, 1_1_1_1
0.45, 0F_0F_0F, 1_1_1_1, 1_0_1_1
0.10, 0F_0F_0F, 1_1_1_1, 0_1_1_1
0.99, 0F_0F_0F, 0_0_1_1, 1_1_0_0
EOD
uniqX = uniqY = ' '
addToList(uniq,col) = uniq.(strstrt(uniq,' '.strcol(col).' ') ? '' : strcol(col).' ' )
getIdx(list,s) = (_c=NaN, sum[_i=1:words(list)] (word(list,_i) eq s ? _c=_i : NaN) , _c)
set datafile separator comma
stats $Data u (uniqX=addToList(uniqX,3), uniqY=addToList(uniqY,4)) nooutput
set key noautotitle
set xtic noenhanced rotate by 90 right
set ytic noenhanced
set offsets 0.5,0.5,0.5,0.5
set bmargin 4
set size ratio -1
set grid x,y
set palette rgb 33,13,10
plot $Data u (getIdx(uniqX,strcol(3))):(getIdx(uniqY,strcol(4))):1:xtic(3):ytic(4) w p pt 5 ps 7 lc palette
### end of script
Result:

Plotting Condition Lines

Suppose I have the following data:
"1,5"
"2,10"
""
"3,4"
"4,2"
""
"5,6"
"6,10"
I want to graph this using gnuplot with a line between each condition, similar to this display:
How might this be accomplished? I have looked into gridlines, but that does not seem to suit my need. I am also looking for a solution that will automatically draw condition / phase lines between each break in the data set.
As mentioned in the comments and explained in the linked question and its answers, you can draw arbitrary lines manually via set arrow ... (check help arrow).
However, if possible I don't want to adjust the lines manually every time I change the data or if I have many different plots.
But, hey, you are using gnuplot, so, make it automated!
To be honest, within the time figuring out how it can be done I could have changed a "few" lines and labels manually ;-). But now, this might be helpful for others.
The script below is written in such a way that it doesn't matter whether you have zero, one or two or more empty lines between the different blocks.
Comments:
the function valid(1) returns 0 and 1 if column(1) contains a valid number (check help valid).
the vertical lines are plotted with vectors (check help vectors). The x-position is taken as average of the x-value before the label line and the x-value after the label line. The y-value LevelY is determined beforehand via stats (check help stats).
the labels are plotted with labels (check help labels) and positioned at the first x-value after each label line and at an y-value of LevelY with an offset.
Script:
### automatic vertical lines and labels
reset session
$Data <<EOD
Baseline
1 10.0
2 12.0
3 10.5
4 11.0 # zero empty lines follow
Treatment
5 45.0
6 35.0
7 32.5
8 31.0 # one empty line follows
Baseline
9 14.0
10 12.8
11 12.0
12 11.3 # two empty lines follow
Treatment
13 35.0
14 45.0
15 45.0
16 37.0
EOD
set offset 1,1,1,1
set border 3
set title "Student Performance" font ",14"
set xlabel "Sessions"
set xtics 1 out nomirror
set ylabel "Number of Responses"
set yrange [0:]
set ytics out nomirror
set key noautotitle
set grid x,y
stats $Data u 2 nooutput
LevelY = STATS_max # get the max y-level
getLinePosX(col) = (v0=v1,(v1=valid(col))?(x0=x1,x1=column(1)):0, v0==0?(x0+x1)/2:NaN)
getLabel(col) = (v0=v1,(v1=valid(col))?0:(h1=strcol(1),h0=h1),column(1))
plot x1=NaN $Data u (y0=(valid(1)?$2:NaN),$1):(y0) w lp pt 13 ps 2 lw 2 lc "red", \
x1=v1=NaN '' u (getLinePosX(1)):(0):(0):(LevelY) w vec nohead lc "black" lw 1.5 dt 2, \
v1=NaN '' u (getLabel(1)):(LevelY):(sprintf("%s",v0==0?h0:'')) w labels left offset 0,1.5 font ",12"
### end of script
Result:

Gnuplot - fitting function to a certain value, problem with the last (first) row of data file

Of late I have been troubling with two issues during some simple plotting.
I'm trying to plot several functions (I suppose the syntax for that can be much simplier), where every one of them fits to just one row of data.
Data file:
11[V] 2.92 4.64 0.04 0.04 0.031[mA]
9[V] 3.32 4.72 0.04 0.04 0.025[mA]
8[V] 3.52 4.76 0.04 0.04 0.022[mA]
7[V] 3.72 4.80 0.04 0.04 0.019[mA]
6[V] 3.92 4.88 0.04 0.04 0.016[mA]
4[V] 4.32 4.92 0.04 0.04 0.010[mA]
Gnuplot commands:
set terminal epscairo color enhanced
set encoding utf8
set xrange[2.8:4.6]
set key left top
set grid
set xlabel 'Napięcie na złączu kolektor-emiter [V]'
set ylabel 'Prąd płynący przez złącze kolektor-emiter [mA]'
set output "dat1_2.eps"
f1(x)=a1*tanh(x)
fit f1(x) "dat1_2.dat" every ::::1 u 2:(($3-0.65)/0.25) via a1
f2(x)=a2*tanh(x)
fit f2(x) "dat1_2.dat" every ::1::2 u 2:(($3-0.65)/0.25) via a2
f3(x)=a3*tanh(x)
fit f3(x) "dat1_2.dat" every ::2::3 u 2:(($3-0.65)/0.25) via a3
f4(x)=a4*tanh(x)
fit f4(x) "dat1_2.dat" every ::3::4 u 2:(($3-0.65)/0.25) via a4
f5(x)=a5*tanh(x)
fit f5(x) "dat1_2.dat" every ::4::5 u 2:(($3-0.65)/0.25) via a5
f6(x)=a6*tanh(x)
fit f6(x) "dat1_2.dat" every ::5 u 2:(($3-0.65)/0.25) via a6
#there is a long plotting line below
plot "dat1_2.dat" using 2:(($3-0.65)/0.25):4:($5/0.25) with xyerrorbar title "Zależność zmierzona", "dat1_2.dat" u ($2+0.07):(($3-0.65)/0.25-0.05):6 with labels notitle font 'Verdana,7.5', f1(x) notitle lt rgb "blue", f2(x) notitle lt rgb "blue", f3(x) notitle lt rgb "blue", f4(x) notitle lt rgb "blue", f5(x) notitle lt rgb "blue", f6(x) notitle lt rgb "blue"
The result of this is:
[...]
variance of residuals (reduced chisquare) = WSSR/ndf : 0.0116479
Final set of parameters Asymptotic Standard Error
======================= ==========================
a5 = 17.0097 +/- 0.07636 (0.4489%)
Read 1 points
line 0: No data to fit
line 0: undefined variable: a6
I have very little idea how to make gnuplot use the last (first?) row. Making a simple trick of doubling the last row of the data file yields expected result but is too nasty for me and I would like to understand what happens here.
The second issue is, how to make gnuplot fit a function to go through a certain point. Let me show what I mean:
https://i.imgur.com/WtLSpj4.png
As you can see, fitted functions are not going 'through' the values computed (neglecting errorbars). That's quite surprising for me, as having only one point to fit to I expected gnuplot to do what I mentioned. What command would fit f functions in this desired fashion?
With every ::::0, or every ::1::2 you select two points, through which gnuplot can fit, but every ::5 selects only a single point through which gnuplot cannot fit.
However, from your explanation I conclude, that you only need to compute the correct scaling factor given a single point. Given the values in a single row are x0 and y0, your function through this point is
f0(x) = (y0 - 0.65)/(0.25 * tanh(x0)) * tanh(x)
To get the correct point for calculating I first plot the single point and while doing that, I save the coordinates in two variable, which are used subsequently for plotting the respective function:
y(ydat) = (ydat - 0.65)/0.25
plot "dat1_2.dat" using (x0=$2):(y0=y($3)):4:($5/0.25) every ::::0 with xyerrorbars title "first",\
y0/tanh(x0) * tanh(x) lc rgb "blue" notitle
Using array, which is available since gnuplot 5.2, this can be nicely plotted in loops over all lines:
y(ydat) = (ydat - 0.65)/0.25
set xrange [2.8:4.6]
N = 6
array X[6]
array Y[6]
array Labels[6] = [ "first", "second", "third", "fourth", "fifth", "sixth" ]
plot for [i=1:N] "dat1_2.dat" using (X[i]=$2):(Y[i]=y($3)):4:($5/0.25) every ::(i-1)::(i-1) with xyerrorbars title Labels[i],\
for [i=1:N] Y[i]/tanh(X[i]) * tanh(x) lc rgb "blue" notitle

Can't use palette to fill object with colour

I was trying to plot number of particles in a square lattice. and I need each one to be coloured different. So I tried using palette.. by picking some random numbers but it always gives me black rectangles.. what should I do?
set obj rect from 1,5 to 2,6 fc palette 0.454545 → this is what is not working for me.
This is the image with all same color. I need different colour for each particle:
Plot using the boxxyerror style, and fill the boxes:
set size ratio -1
set style fill solid
plot 'file.dat' using 1:2:(0.1):(0.1):3 linecolor palette with boxxyerror
This would plot a square of size 0.2 at each position given by the first and second columns. The color is taken from the third column and mapped to the current palette. You must adapt that to your actual data format.
Working example using random pseudo-data ('+'):
set xrange [-0.05:1.05]
f = "int(rand(0) * 20)/20.0"
set style fill solid
set size ratio -1
plot '+' using (#f):(#f):(0.025):(0.025):(#f) linecolor palette notitle with boxxyerror
see What I gotI could get this working,what I did is initially set the pallette by the commands like "set palette model RGB defined ( 0 'green', 1 'blue', 2 'red', 3 'orange' )" ,"set palette model HSV defined ( 0 0 1 1, 1 1 1 1 )"(I got these from here-http://gnuplot.sourceforge.net/demo/pm3dcolors.html). Then I set rectangles as "set obj rect from x1,y1 to x2,y2 fc palette frac 0.57" . But I could see that there were some gaps between the squares and I could understand that it was because of problem with border so I added this "fs border palette frac 0.57",same colour. Even after doing these It wouldn't come out by the simple command "plot 0". So I had to modify it as "plot 0 lc palette frac 0.24 " (0.57 / 0.24 I just meant as example.. as you know it would be anything between 0 and 1). Now to remove the colorbox I used "unset colorbox". But why I had to write "plot 0 lc palette frac 0.24 " ?, to wakeup the palette? ,Is there any other way to show out the rectangles that we have already set without using a plot command ?

Is it possible to read the value of a label in gnuplot from a file

Creating labels in gnulot is quite simple
set label "<value>" at <x,y> ...
But I want to read the value of a label in gnuplot from a file.
The lines in the file look this way:
...
400 300 8 0.200214 1.00193 7.42157 8.623714 86.06 13.94 1.26
800 600 1 0.2055 0.1938 34.9172 35.3165 98.86 1.14 1.00
800 600 2 0.2066 1.5514 21.1664 22.9244 92.33 7.67 1.54
800 600 4 0.2027 1.6316 14.9445 16.7788 89.06 10.94 2.10
800 600 8 0.242 1.8385 12.7261 14.8066 85.94 14.06 2.38
1024 768 1 0.2212 0.2217 55.1782 55.6211 99.20 0.80 1.00
...
I just need the values from the 10th column as labels.
Is it possible to realize something like this:
set label from <inputfile> <column_of_inputfile> <row_of_inputfile> ...
?
Thanks for any help.
This solution worked for me:
set title "800x600"
set xlabel "Nodes [#]\n"
set ylabel "Speedup" offset 2
set xrange [-0.55:3.55]
set yrange [0:5]
set style data histograms # plot boxes
set boxwidth 0.75 # have a gap between the boxes
plot 'inputfile.csv' every ::9::12 using 10:xtic(3) title "800x600" lc rgb "grey",\
'' every ::9::12 using :10:10 with labels center offset 0,1 tc rgb "black"
The first plot line does in detail:
every ::9::12 => plot line 9-12 of the inputfile.
using 10:xtic(3) => the value of column number 10 specifies the height of the data histograms. The value of column 3 is used for labeling the x axis.
The second plot line plots the content of column 10 of the lines 9-12 as label in center orientation above the data histograms.
The image shows the result.

Resources