Search code examples
gnuplotscatter-plot

Gnuplot: Scatter plot and density


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:

enter image description here

However I want something like that

enter image description here

Is that possible in Gnuplot? Any ideas?


Solution

  • (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.

    Script: works with gnuplot>=5.2.0

    ### 2D density color plot
    reset session
    
    t1 = time(0.0)
    # create some random rest data
    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("Time data creation: %.3f s",(t0=t1,t1=time(0.0),t1-t0))
    
    # for each datapoint: how many other datapoints are within radius R
    R = 0.5     # Radius to check
    Dist(x0,y0,x1,y1) = sqrt((x1-x0)**2 + (y1-y0)**2)
    set print $Density
        do for [i=1:|$Data|] {
            x0 = real(word($Data[i],1))
            y0 = real(word($Data[i],2))
            c  = 0
            stats $Data u (Dist(x0,y0,$1,$2)<=R ? c=c+1 : 0) nooutput
            d = c / (pi * R**2)             # density: points per unit area
            print sprintf("%g %g %d", x0, y0, d)
        }
    set print
    print sprintf("Time density check: %.3f sec",(t0=t1,t1=time(0.0),t1-t0))
    
    set size ratio -1   # same screen units for x and y
    set palette rgb 33,13,10
    plot $Density u 1:2:3 w p pt 7 lc palette z notitle
    ### end of script
    

    Result:

    enter image description here