I would like to plot several lines in a gnuplot (version 4.6 or 5.0) using loop and during plotting manipulate with the data.
For simple plotting of the data (without manipulation) i use
plot for [i=2:100] 'data.dat' u 1:i with lines lt 1 lc rgb 'blue' notitle
and everything is fine: Normal result
but!
when i'm trying to manipulate with data in this code:
plot for [i=2:100] 'data.dat' u 1:(i-0.3) with lines lt 1 lc rgb 'blue'
the gnuplot resist to my manipulation and gives the strange result:
The strange result after the second code and assumptions to manipulate on the date. Also I've tried ($i-0.3) instead of (i-0.3) and also without brackets, all this doesn't work. Could anyone help?
Thanks in advance.
Use column(i) to access a column's value for calculation, if the column number is given by a variable i:
plot for [i=2:100] 'data.dat' u 1:(column(i)-0.3)
Related
UPDATE
So apparently, the order of options does matter. Wasn't aware of that. Still,
rowi=1
rowf=7
colour=0
plot for [i=0:rowf-rowi+3] filename.'.csv' u ($0+i):2:3:(colour=colour+1):xtic(1) every ::i+1::i+1 w errorbars pt 7 lc var notitle
will start re-using colour after the eight entry where I want a different colour for each of the 10 points plotted.
How do I do that?
In gnuplot, the lc (linecolor) and pt (pointtype) parameters belong to the w (with) clause (see help plot with), so putting notitle between pt 7 and lc var doesn't work. If you move the notitle clause to the end of the plot command line, this will fix the error you are getting. Like this:
plot for [i=0:rowf-rowi+3] filename.'.csv' u ($0+i):2:3:xtic(1) every ::i+1::i+1 w errorbars pt 7 lc var notitle
Without lc var, by default the colours will eventually repeat but you can set the palette to anything you like. See: Gnuplot repeats colors in rowstack histograms
I am using Gnuplot to draw step functions from an input file:
plot 'myFile' using 1:2 with steps
I want to fill underneath the plot. something like
plot 'myFile' using 1:2 with filledcurves
But Gnuplot fill underneath the diagram by drawing a line between consecutive points.
How can I fill in underneath the step function?
Use the fillsteps plotting style, which is the same as steps, but the area between the curve and y=0 is filled:
set samples 11
set xrange [0:10]
plot '+' with fillsteps fs solid 0.3 noborder lt 1,\
'+' with steps lt 1 lw 4
Creating a normiles stack diagram works perfectly fine, now I want to use a different color for the boxes fitting in a specific range.
For this, I adopted the following:
set palette maxcolors 2
set palette defined ( 0 '#C0504D', 1 '#00B059')
plot dataFileCity using (rounded(stringcolumn(1) eq city ? $2 : NaN)):
(100 / (bin_width * STATS_records)):($2 > 1300 ? 0 : 1)
smooth frequency with boxes palette
If column 2 has a value highter than 1300 I would like to have a different color.
Which is based on:
Normalized histograms in gnuplot with added function plot
And
Color bars in different colors for some specific values in Gnuplot
However, I am afriad that the smooth frequency makes the thing not work. How can I pass the value such that is creates the a different color?
I know this is nearly 8 years old, but I had the same issue and based on Christoph's comment above I was able to figure out a way.
Below is the graph I wanted:
However selecting certain rows only by way of the ternary and NaN does not play nice with smooth freq, and my histogram was wrong (seemed bins were drawn over one another and frequencies weren't as high as they should've been).
This did not work:
plot \
'filename' using ($1 >= 0 ? $1 : NaN) notitle smooth freq with boxes fillcolor rgb "green", \
'filename' using ($1 < 0 ? $1 : NaN) notitle smooth freq with boxes fillcolor rgb "red"
In the manual for gnuplot 5.4.2, this section describes an experimental feature which, combined with set table, allowed me to achieve the above graph.
[EXPERIMENTAL] To select only a subset of the data points for tabulation you can provide an input filter condition (if ) at the end of the command. Note that the input filter may reference data columns that are not part of the output. This feature may change substantially before appearing in a released version of gnuplot.
plot <file> using 1:2:($4+$5) with table if (strcol(3) eq "Red")
-- p207 gnuplot v5.4.2 manual
So the approach is:
Use set table $my_data_block_green to set the next plot command to output to the $my_data_block_green data block. We'll create one data block for each colour and this is the first.
Use plot <file> with table if (<condition_for_green>) to write to the green data block only rows matching <condition_for_green>.
Use set table $my_data_block_red (as in point 1).
Use plot <file> with table if (<condition_for_red>) to write to the red data block only rows matching <condition_for_red>.
Cease writing plot commands to tables with unset table.
Plot as normal, referencing the data blocks instead of <file>.
Relevant code (not the full code for graph above):
set table $db1
plot <filename> using 7:(1) with table if ($7 >= 0)
set table $db2
plot <filename> using 7:(1) with table if ($7 < 0)
unset table
plot \
'$db1' using $1:.. .. fillcolor rgb "green", \
'$db2' using $1:.. .. fillcolor rgb "red"
Hope that saves someone a few mins.
Adding to #TKF's answer... There is no need to split the smooth freq data into two tables.
Instead, plot it into one table and set the color via lc rgb variable and by defining an appropriate function.
The following example works for gnuplot>=5.2, with some modifications also with earlier versions.
Code:
### histogram with split colors
reset session
# create some random test data
set print $Data
do for [i=1:2000] {
print sprintf("%g",int(invnorm(rand(0))*100))
}
set print
stats $Data u 1 nooutput
xmin = STATS_min
xmax = STATS_max
N = 20
myWidth = (xmax-xmin)/N
bin(col) = myWidth*floor(column(col)/myWidth)+myWidth/2.
set boxwidth myWidth
set key noautotitle
set style fill solid 0.3
set grid x,y
set table $Histo
plot $Data u (bin(1)) smooth freq
unset table
myColor(col) = column(col)<0 ? 0xff0000 : 0x00cc00
plot $Histo u 1:2:(myColor(1)) w boxes lc rgb var
### end of code
Result:
Intro
In gnuplot there's a solution to create histogram from file named hist.dat what likes
1
2
2
2
3
by using commands
binwidth=1
set boxwidth binwidth
bin(x,width)=width*floor(x/width) + binwidth/2.0
plot [0:5][0:*] "hist.dat" u (bin($1,binwidth)):(1.0) smooth freq with boxes
that generates a histogram like this one from other SO page.
Question
How can I fit my function to this histogram? I defined a Gaussian function and initialized its values by
f(x) = a*exp(-((x-m)/s)**2)
a=3; m=2.5; s=1
and in the output the function follow the histogram well.
Unfortunatelly I cannot fit to this histogram using command
fit f(x) "hist.dat" u (bin($1,binwidth)):(1.0) smooth freq via a,m,s
^
Need via and either parameter list or file
So how can I fit my function without creating a new file containing the binned values?
I'm facing a similar problem and I found a kind of not very ellegant solution.
binwidth=1
set boxwidth binwidth
bin(x,width)=width*floor(x/width) + binwidth/2.0
set table 'hist.temp'
plot [0:5][0:*] "hist.dat" u (bin($1,binwidth)):(1.0) smooth freq with boxes
unset table
And then you can do the fit of the file as you prefer. I know that probably there are some better way of doing this, but for me it is a fast and working solution. I hope this will be helpful for you.
Cheers!
I used this a nd it worked:
gauss(x)=a/(sqrt(2*pi)sigma)*exp(-(x-mean)**2/(2*sigma**2))
fit gauss(x) 'data.txt' via a,sigma,mean
after 83 iterations GNUplot calculated me a, sigma, and mean
I am new to R for plotting, and I wish to do contour plots for several files. and here is what I have got so far. My file has 3 columns, X,Y,Z, and with some nan values. Since lattice does not allow Inf/NaN values, I had to remove them prior, and do some interpolation.
data <- read.table("file", sep=",", header=T)
mydata <- na.omit(data)
library(akima)
library(lattice)
s = interp(mydata$X, mydata$Y, mydata$Z)
filled.contour(s, xlim= c(5,25), ylim=c(40,180))
This does gives some results, but there are things I am not able to do:
To get contour lines on the graph.
Also there are like 3 files with different z ranges, say one from (0-18), (0-20), (0-25). I wish to adjust and rescale them to provide similar color scale on graph, for instance, the '15' value should be similar color on all three.
I am more familiar with gnuplot, but there also the problem is with the ranges, as the range always autoscale to color, and it seems difficult to control the range. Any help with that is also deeply appreciated.
I may be doing something wrong, so in case anybody could help me out, and provide to right direction, or right software, I will be grateful.
There are demos here for how to make contours in gnuplot. Are you having trouble in the sense that you have code to make a contour plot but it does not work?
To answer your second question, in gnuplot the command you probably want is
set cbrange [CB_MIN:CB_MAX]
This sets the range of values which will be colored according to the current palette. You would just have to issue the same set cbrange command for all three plots you are making. If you want to automatically set the cbrange to the min/max on all files, you can use the stats command (in version 4.6 or newer, otherwise it is more tricky):
stats 'datafile1' using 3 name 'd1'
stats 'datafile2' using 3 name 'd2'
stats 'datafile3' using 3 name 'd3'
datamin_z = (d1_min<d2_min&&d1_min<d3_min?d1_min:d2_min<d3_min?d2_min:d3_min)
datamax_z = (d1_max>d2_max&&d1_max>d3_max?d1_max:d2_max>d3_max?d2_max:d3_max)
set cbrange [datamin_z:datamax_z]