I would like to make convex hull figure giving Gnuplot the vertices that join the surfaces of the figure.
I have been testing, but I have not any clear way to make this.
I can plot the points with this script:
set encoding iso_8859_1
set terminal postscript eps enhanced color size 4.0in,4.0in #"Helvetica" 16
set output "RG1.eps"
set view 50,220
unset colorbox
splot "convex1.dat" with lines notitle ,\
"convex1.dat" u 1:2:3 with points palette pointsize 3 pointtype 7
where convex1.dat contains these points
0 0 0
0 0 0.285957
0 0.285957 0.285957
0 0.3812378724 0.1906189362
0 0.571914 0
0.1906761276 0.3812378724 0.1906189362
0.285957 0.285957 0.285957
0.571914 0 0
0.571914 0 0.285957
The representation of this script is:
I can make the convex hull with these points with the Mathematica environment and create the type of figure I am looking for:
The question is: how can I make a convex hull, like the Mathematica figure, with Gnuplot, and how could I use transparency to make figures with comparing two convex hulls with the same axis?
Gnuplot is primarily a renderer for structured numerical data; it's not much of a mathematical processing system, or a renderer for geometry data. There's the pm3d style for splot which allows you to plot arbitrary polygon collections, but it doesn't do hidden surface removal, let alone complex renderings based on the intersection of multiple polygons. In fact, the documentation itself says:
Gnuplot is not [a] virtual reality tool to calculate intersections of filled
polygon meshes.
For this sort of thing, you'll want to use an actual mathematical processing package (like Mathematica!) which can output to a vector format, and then use that directly rather than going through Gnuplot.
Related
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.
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.
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)
gnuplot will plot a data file with vectors.
I would like to set something like isosamples=40 and
have gradient vectors plotted for a 2D function.
I know I could write a python program to generate
the data file for the vectors but
I would prefer to do the entire operation within gnuplot.
Any advice?
Would this be a worthy improvement to gnuplot if not yet implemented?
You can use the vectors style and do the computations in gnuplot using the special filename ++.
Suppose that I wish to graph a direction field for the differential equation y'=y*sin(x). I could do this with the following:
set xrange[-2:2]
set yrange[-2:2]
set samples 30
set isosamples 30
unset key
f(x,y) = y*sin(x)
lf(x,y) = sqrt(1+f(x,y)**2)
lyf(x,y) = f(x,y)/lf(x,y)
plot '++' u 1:2:(0.1/lf($1,$2)):(0.1*lyf($1,$2)) with vectors
All of my calculations are done in gnuplot. I compute the direction of the vectors, and scale them to have a length of 0.1, all in the plot command.
I use the special filename '++' which generates a set of points equally spaced over the x and y plot ranges.
See 'help special-filenames' for more details on that.
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