Gnuplot x(y) smoothing - gnuplot

How do I smooth the data presented in the form x(y)? Gnuplot smoothing function of to invalid handles such cases.
As an example:
File(T-L.dat):
0.00 0.0
0.10 0.1
0.15 0.2
0.40 0.3
0.60 0.4
0.50 0.5
0.60 0.6
0.40 0.7
0.15 0.8
0.10 0.9
0.00 1.0
What I want.
Gnuplot session:
knkd#SCP71:~/MEAS/HEAT$ gnuplot
G N U P L O T
Version 4.6 patchlevel 4 last modified 2013-10-02
Build System: Linux x86_64
Copyright (C) 1986-1993, 1998, 2004, 2007-2013
Thomas Williams, Colin Kelley and many others
gnuplot home: http://www.gnuplot.info
faq, bugs, etc: type "help FAQ"
immediate help: type "help" (plot window: hit 'h')
Terminal type set to 'wxt'
gnuplot> plot "T-L.dat" with lines
What I have.
Add smooth:
gnuplot> plot "T-L.dat" with lines smooth csplines
Result not good too (only 2 links, sorry).
Other features also not give the result that I wanted to.
But really I need a spline.

Correct, gnuplot can smooth with splines only data of the form y(x). For this, the data is rendered monotonic in x before smoothing it. You data is symmetric with respect to y, this is why you get a straight line as result of the smoothing.
In order to smooth your data with respect to y, you must first exchange the axes and save the result of the smoothing to a temporary file. This is then plotted with the correct axis selection:
set table 'T-L-smoothed.dat'
plot 'T-L.dat' using 2:1 smooth csplines
unset table
plot 'T-L-smoothed.dat' using 2:1 with lines, 'T-L.dat' with points pt 7

Related

Gnuplot smooth curve through frequency points + filled area under curve

I am a gnuplot-newbie and am stuck with the following situation. Based on this I have a gnuplot script as follows:
clear
reset
set key off
set border 3
set style fill solid 1.0 noborder
bin_width = 0.01;
set boxwidth bin_width absolute
bin_number(x) = floor(x/bin_width)
rounded(x) = bin_width * ( bin_number(x) + 0.5 )
plot '1000randomValuesBetween0and1.dat' using (rounded($1)):(1) smooth frequency
Which was a good first step; but I would like to have a smooth curve through the points that are generated by counting the frequency. with filledcurves lacked what I wanted in 2 ways. First it is not smoothed (I would prefer something like bezier which is not usable after with); second the filling is done in a rather unexpected way which doesn't fit my needs (for me unexpected). See this picture .
To give a little bit more context: I ultimately want to use this to generate
violin plots with gnuplot without having to do the binning beforehand so I can just give my script a single-column data-file and am ready to go.
EDIT: I tried adapting the "normal" density plot from this demo as another first step, but I failed; I read in the documentation that bandwidth should be 1/#points so it
should be 0.001 in my case meaning I tried this:
set border 3 front lt black linewidth 1.000 dashtype solid
set style increment default
set style data filledcurves
set xtics border in scale 0,0 nomirror norotate autojustify
set xtics norangelimit 0.00000,0.5,1.0
set title "Same data - kernel density"
set title font ",15" norotate
plot 'random01.dat' using 1:(1) smooth kdensity bandwidth 0.001 with filledcurves above y lt 9
which results in this picture:.
Setting no bandwith or lower/higher values didn't solve the issue.
The plot specifies using 1:(1) because I just have a single column so according to the doc the first value should be this column and as the second value would specify a weighting which should be 1/#points according to doc.
EDIT2: Setting bandwidth to the ideal value or not setting it at all always yields the same result which doesn't change anything except the scale of the y-axis with changing the weighting.
My data are 1000 values in a range between 0 and 1 (created randomly for testing purposes).
Here the new plot
EDIT3: zooming out may show another aspect of the problem as the plot seems to extend outside the interval of the given values (I checked the values and there are no examples <0 or >1). Here's the graph:
The demo 'violinplot.dem' included with the gnuplot distribution package and also available online shows how to do what you want using the combination "smooth kdensity" and "with filledcurve" applied to unbinned data.
Online version here: violin plot demo
Notes:
You mis-read the documentation. 1/N is not the recommended bandwidth, it is the normalized uniform weight. The plot you showed initially looks like the bandwidth was set far too low. What is the range of values in your data?
I suggest letting the program calculate the "ideal" bandwidth for you and then adjusting it afterwards if you think it is too large. The ideal value is stored in GPVAL_KDENSITY_BANDWIDTH. Increasing the bandwidth will make the envelope smoother; decreasing it will emphasize local spikes.

Getting smooth curve with gnuplot

I'm not getting smooth curve on gnuplot.
This is my code:
set style line 3 lc rgb '#09ad00' lt 1 lw 1.5 #green
set style line 1 lc rgb '#0060ad' lt 1 lw 2 #blue
set style line 2 lc rgb '#dd181f' lt 1 lw 2 #red
plot [-1:1] f1(x) with line ls 3,f2(x) with line ls 1,f1(x)+f2(x) with line ls 2
I'm getting this plot
while I'm expecting this type of curve
You haven't shown what your particular functions are, but this is almost certainly a sampling problem. Gnuplot doesn't really draw curves for functions - it actually computes the functions at multiple points and connects them with straight lines, similarly to what would happen if you were plotting a data file. The number of points that it computes is user settable.
Suppose that I do plot sin(x) and see this:
Here the sampling rate is set pretty low. We can look at the individual points in order to see what is going on.
In order to improve this, I need to increase the sampling rate by using the set samples ? command. The default is 100 (in 5.0 patch level 6). Depending on how rapidly the function changes, higher values may be needed. I usually set it to around 1000 with set samples 1000. This changes the graph to
which produces a much nicer smooth curve. Again, this is just a bunch of points connected by straight lines, but when there are a lot of these, it looks like a smooth continuous curve.
We can look at the individual points again (using a sampling rate of 100 as 1000 is too many to clearly see the points)
We can also see here that there is not much difference between the graph with 1000 points and 100 points. In the case of a sine curve, 100 is enough to see a smooth graph, but with a faster changing curve, we may need more.
The set samples command takes (optionally) two values, but the second value is only used for 3d plots. You can find out more with the help samples command.

Gnuplot: arc circles with no line

I am trying to plot an arc segment using Gnuplot this circle command:
set obj 1 circle at 9 size 3 arc [0:180] fc rgb "blue" lw 1
And I'm getting
But I would like to get
Is there a simple way to do that? Or do I need to draw the arc and then "erase" the part I don't need?
I was looking for the same function, but it seems that gnuplot doesn't support such features. Moreover, sometimes you need to plot such an arc using a non-polar plot and that doesn't make your life easier.
Nevertheless, gnuplot allows you to do some tricks.
You can always set an arc and use any pair of angles you need.
Next, you simply reverse the order of angles so that your initial one becomes your final and vice versa. Also, the colour has to be white.
set object 2 circle at 1.5, 0.8 arc [-90:90] size 1 fc rgb "black" lw 4
set object 3 circle at 1.5, 0.8 arc [90:-90] size 1 fc rgb "white" lw 4
In addition, when you work with vectorized images, it's better to make the second arc a bit thicker, say, lw 5, otherwise some minor artefacts are observed.
I think your only recourse is to plot a function, something like
set parametric
plot [-pi/2:pi/2] sin(t),cos(t)

Histogram in logarithmic scale in gnuplot

I have to plot an histogram in logarithmic scale on both axis using gnuplot. I need bins to be equally spaced in log10. Using a logarithmic scale on the y axis isn't a problem. The main problem is creating the bin on the x axis. For example, using 10 bins in log10, first bins will be [1],[2],[3]....[10 - 19][20 - 29].....[100 190] and so on. I've searched on the net but I couldn't find any practical solution. If realizing it in gnuplot is too much complicated could you suggest some other software/language to do it?
As someone asked I will explain more specifically what I need to do. I have a (huge) list like this:
1 14000000
2 7000000
3 6500000
.
.
.
.
6600 1
8900 1
15000 1
19000 1
It shows, for example, that 14 milions of ip addresses have sent 1 packet, 7 milions 2 packets.... 1 ip address have sent 6600 packets, ... , 1 ip address have sent 19000 packets. As you can see the values on both axes are pretty high so I cannot plot it without a logarithmic scale.
The first things I tried because I needed to do it fast was plotting this list as it is with gnuplot setting logscale on both axes using boxes. The result is understandable but not too appropriate. In fact, the boxes became more and more thin going right on the x axis because, obviously, there are more points in 10-100 than in 1-10! So it became a real mess after the second decade.
I tried plotting a histogram with both axis being logarithmically scaled and gnuplot through the error
Log scale on X is incompatible with histogram plots.
So it appears that gnuplot does not support a log scale on the x axis with histograms.
Plotting in log-log scale in GnuPlot is perfectly doable contrary to the other post in this thread.
One can set the log-log scale in GnuPlot with the command set logscale.
Then, the assumption is that we have a file with positive (strictly non-zero) values both in the x-axis, as well as the y-axis. For example, the following file is a valid file:
1 0.5
2 0.2
3 0.15
4 0.05
After setting the log-log scale one can plot the file with the command:
plot "file.txt" w p where of course file.txt is the name of the file. This command will generate the output with points.
Note also that plotting boxes is tricky and is probably not recommended. One first has to restrict the x-range with a command of the form set xrange [1:4] and only then plot with boxes. Otherwise, when the x-range is undefined an error is returned. I am assuming that in this case plot requires (for appropriate x-values) some boxes to have size log(0), which of course is undefined and hence the error is returned.
Hope it is clear and it will also help others.
Have you tried Matplotlib with Python? Matplotlib is a really nice plotting library and when used with Python's simple syntax, you can plot things quite easily:
import matplotlib.pyplot as plot
figure = plot.figure()
axis = figure.add_subplot(1 ,1, 1)
axis.set_yscale('log')
# Rest of plotting code

Plot histogram with specified patterns for different categories in GNUPLOT

I'm now gonna plot a 10-category histogram with GNUPLOT. Since number of categories is relative large, I want to specify patterns for different categories myself instead of applying the default pattern setting making different categories easy distinguished, e.g. fill the first category with dash-line while the second shaded, etc.
Is there any parameter can be employed to specify a pattern in the plot command? Any hints/advice will be highly appreciated. Thanks in advance.
Best Regards!
You can use with boxes fs [pattern|solid] <style-id>.
0 0.0 0.0
1 0.3 0.6
2 1.6 1.6
3 0.3 1.5
4 0.6 3.6
5 0.3 4.3
6 0.3 0.7
7 5.5 5.5
8 6.6 6.6
9 5.2 5.2
10 8.3 8.3
11 2.7 5.0
12 2.8 8.3
13 3.3 2.8
14 7.9 3.9
15 9.9 7.9
16 15.3 15.3
17 14.7 14.7
18 3.8 18.1
19 18.1 12.1
Gnuplot script:
set style data hist
set style histogram rowstacked
plot 'test.dat' us 2:xtic(1) fs solid 1 ls 3, '' us 3 fs pattern 1
See this link for more detail:
http://t16web.lanl.gov/Kawano/gnuplot/plot5-e.html
gnuplot fillstyle demo
It is an interesting problem. After read your question I wrote a blog to talk about it. May be you can have a look. The link is here:
http://gnuplot-surprising.blogspot.com/2011/09/plot-histograms-using-boxes.html

Resources