I have x- and y-data points representing a star cluster. I want to visualize the density using Gnuplot and its scatter function with overlapping points.
I used the following commands:
set style fill transparent solid 0.04 noborder
set style circle radius 0.01
plot "data.dat" u 1:2 with circles lc rgb "red"
The result:
However I want something like that
Is that possible in Gnuplot? Any ideas?
(edit: revised and simplified)
Probably a much better way than my previous answer is the following:
For each data point check how many other data points are within a radius of R
. You need to play with the value or R
to get some reasonable graph.
Indexing the datalines requires gnuplot>=5.2.0 and the data in a datablock (without empty lines). You can either first plot your file into a datablock (check help table
) or see here:
gnuplot: load datafile 1:1 into datablock
The time for creating this graph will increase with number of points O(N^2) because you have to check each point against all others. I'm not sure if there is a smarter and faster method. The example below with 1200 datapoints will take about 4 seconds on my laptop. You basically can apply the same principle for 3D.
Addition: (contour plot)
x:y:density
), you can either create a "3D"-splot or a 2D-contour plotdgrid3d
for this and you need to play with the dgrid3d
options (check help dgrid3d
), e.g. gauss <number>
splot
and set view map
is the arrangement/alignment of the margins. Better would be plot
, but then you have to plot your generated contours first into another datablock.Script: requires gnuplot>=5.2.5, Oct. 2018 (because of splot ... nosurface
)
### 2D density color and contour plot
reset session
# create some random test data
t0 = time(0.0)
set table $Data
set samples 700
plot '+' u (invnorm(rand(0))):(invnorm(rand(0))) w table
set samples 500
plot '+' u (invnorm(rand(0))+2):(invnorm(rand(0))+2) w table
unset table
print sprintf("Data creation: %.3f sec",(t1=time(0.0))-t0,t0=t1)
stats $Data u 0 nooutput # get number of datalines
Rows = STATS_records
R = 0.7 # Radius to check
# for each datapoint: how many other datapoints are within radius R
distance(x0,y0,x1,y1) = sqrt((x1-x0)**2 + (y1-y0)**2)
set print $Density
do for [i=1:Rows] {
x0 = real(word($Data[i],1))
y0 = real(word($Data[i],2))
c = 0
stats $Data u (distance(x0,y0,$1,$2)<=R ? c=c+1 : 0) nooutput
d = c / (pi * R**2)
print sprintf("%g %g %d", x0, y0, d)
}
set print
print sprintf("Density check: %.3f sec",(t1=time(0.0))-t0,t0=t1)
set size ratio -1
set palette rgb 33,13,10
set cblabel "points per unit area"
set multiplot layout 1,2
plot $Density u 1:2:3 w p pt 7 lc palette z notitle
set dgrid3d 100,100 gauss 0.2
set contour
set cntrparam levels 10
set view map
set size ratio -1
set grid x,y
set key noautotitle out samplen 1
unset colorbox
set margins 0,0,0,0
splot $Density u 1:2:3 w l palette z nosurface
print sprintf("Contour plot: %.3f sec",(t1=time(0.0))-t0,t0=t1)
unset multiplot
### end of script
Result:
Data creation: 0.079 sec
Density check: 4.620 sec
Contour plot: 0.889 sec