Gnuplot:散点图和密度
Gnuplot: Scatter plot and density
我有代表星团的 x 和 y 数据点。我想使用 Gnuplot 及其具有重叠点的散点函数可视化密度。
我使用了以下命令:
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"
结果:
不过我想要那样的东西
这在 Gnuplot 中可行吗?有什么想法吗?
是否可以选择使用 imagemagick 对图像进行后处理?
# convert into a gray scale image
convert source.png -colorspace gray -sigmoidal-contrast 10,50% gray.png
# build the gradient, the heights have to sum up to 256
convert -size 10x1 gradient:white-white white.png
convert -size 10x85 gradient:red-yellow \
gradient:yellow-lightgreen \
gradient:lightgreen-blue \
-append gradient.png
convert gradient.png white.png -append full-gradient.png
# finally convert the picture
convert gray.png full-gradient.png -clut target.png
我没试过,但我很确定gnuplot可以直接绘制灰度图。
这是(旋转的)渐变图像:
这是结果:
虽然这个问题相当 "old" 并且问题的解决方式可能有所不同...
这可能更多的是出于好奇和乐趣,而不是出于实用目的。
以下代码仅使用 gnuplot 根据点的密度实现着色。在我的旧计算机上,绘制 1000 个点需要几分钟时间。如果可以改进此代码,尤其是在速度方面(不使用外部工具),我会很感兴趣。
可惜gnuplot不提供排序、查表、合并、转置等基本功能(我知道……它是gnuPLOT……不是分析工具)。
代码:
### density color plot 2D
reset session
# create some dummy datablock with some distribution
N = 1000
set table $Data
set samples N
plot '+' u (invnorm(rand(0))):(invnorm(rand(0))) w table
unset table
# end creating dummy data
stats $Data u 1:2 nooutput
XMin = STATS_min_x
XMax = STATS_max_x
YMin = STATS_min_y
YMax = STATS_max_y
XRange = XMax-XMin
YRange = YMax-YMin
XBinCount = 20
YBinCount = 20
BinNo(x,y) = floor((y-YMin)/YRange*YBinCount)*XBinCount + floor((x-XMin)/XRange*XBinCount)
# do the binning
set table $Bins
plot $Data u (BinNo(,)):(1) smooth freq # with table
unset table
# prepare final data: BinNo, Sum, XPos, YPos
set print $FinalData
do for [i=0:N-1] {
set table $Data3
plot $Data u (BinNumber = BinNo(,),):(XPos = ,):(YPos = ,) every ::i::i with table
plot [BinNumber:BinNumber+0.1] $Bins u (BinNumber == ? (PointsInBin = ,) : NaN) with table
print sprintf("%g\t%g\t%g\t%g", XPos, YPos, BinNumber, PointsInBin)
unset table
}
set print
# plot data
set multiplot layout 2,1
set rmargin at screen 0.85
plot $Data u 1:2 w p pt 7 lc rgb "#BBFF0000" t "Data"
set xrange restore # use same xrange as previous plot
set yrange restore
set palette rgbformulae 33,13,10
set colorbox
# draw the bin borders
do for [i=0:XBinCount] {
XBinPos = i/real(XBinCount)*XRange+XMin
set arrow from XBinPos,YMin to XBinPos,YMax nohead lc rgb "grey" dt 1
}
do for [i=0:YBinCount] {
YBinPos = i/real(YBinCount)*YRange+YMin
set arrow from XMin,YBinPos to XMax,YBinPos nohead lc rgb "grey" dt 1
}
plot $FinalData u 1:2:4 w p pt 7 ps 0.5 lc palette z t "Density plot"
unset multiplot
### end of code
结果:
可能,比我之前的回答更好的方法如下。
在我 8 岁的电脑上,1000 点大约需要 2-3 分钟。您基本上可以为 3D 做同样的事情(参见 )
代码:
### density color plot 2D
reset session
N = 1000 # number of datapoints
Delta = 0.5 # half boxwidth
TimeStart = time(0.0)
# create some dummy datablock with some distribution
set table $Data
set samples N
plot '+' u (invnorm(rand(0))):(invnorm(rand(0))) w table
unset table
print sprintf("Data generated: %.3f sec",time(0.0)-TimeStart)
# end creating dummy data
TimeStart = time(0.0)
# put the datafile/dataset into arrays
stats $Data nooutput
RowCount = STATS_records
array ColX[RowCount]
array ColY[RowCount]
array ColC[RowCount]
do for [i=1:RowCount] {
set table $Dummy
plot $Data u (ColX[[=10=]+1]=,0):(ColY[[=10=]+1]=,0) with table
unset table
}
print sprintf("Data put into arrays: %.3f sec",time(0.0)-TimeStart)
# look at each datapoint and its sourrounding
do for [i=1:RowCount] {
# print sprintf("Datapoint %g of %g",i,RowCount)
x0 = ColX[i]
y0 = ColY[i]
# count the datapoints with distances <Delta around the datapoint of interest
set table $Occurrences
plot $Data u ((abs(x0-)<Delta) & (abs(y0-)<Delta) ? 1 : 0):(1) smooth frequency
unset table
# extract the number from $Occurrences which will be used to color the datapoint
set table $Dummmy
plot $Occurrences u (c0=,0):([=10=]) every ::1::1 with table
unset table
ColC[i] = c0
}
# put the arrays into a dataset again
set print $Data
do for [i=1:RowCount] {
print sprintf("%g\t%g\t%g",ColX[i],ColY[i],ColC[i])
}
set print
print sprintf("Duration: %.3f sec",time(0.0)-TimeStart)
set palette rgb 33,13,10
plot $Data u 1:2:3 w p ps 1 pt 7 lc palette z notitle
### end of code
将导致如下结果:
我有代表星团的 x 和 y 数据点。我想使用 Gnuplot 及其具有重叠点的散点函数可视化密度。
我使用了以下命令:
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"
结果:
不过我想要那样的东西
这在 Gnuplot 中可行吗?有什么想法吗?
是否可以选择使用 imagemagick 对图像进行后处理?
# convert into a gray scale image
convert source.png -colorspace gray -sigmoidal-contrast 10,50% gray.png
# build the gradient, the heights have to sum up to 256
convert -size 10x1 gradient:white-white white.png
convert -size 10x85 gradient:red-yellow \
gradient:yellow-lightgreen \
gradient:lightgreen-blue \
-append gradient.png
convert gradient.png white.png -append full-gradient.png
# finally convert the picture
convert gray.png full-gradient.png -clut target.png
我没试过,但我很确定gnuplot可以直接绘制灰度图。
这是(旋转的)渐变图像:
这是结果:
虽然这个问题相当 "old" 并且问题的解决方式可能有所不同... 这可能更多的是出于好奇和乐趣,而不是出于实用目的。 以下代码仅使用 gnuplot 根据点的密度实现着色。在我的旧计算机上,绘制 1000 个点需要几分钟时间。如果可以改进此代码,尤其是在速度方面(不使用外部工具),我会很感兴趣。 可惜gnuplot不提供排序、查表、合并、转置等基本功能(我知道……它是gnuPLOT……不是分析工具)。
代码:
### density color plot 2D
reset session
# create some dummy datablock with some distribution
N = 1000
set table $Data
set samples N
plot '+' u (invnorm(rand(0))):(invnorm(rand(0))) w table
unset table
# end creating dummy data
stats $Data u 1:2 nooutput
XMin = STATS_min_x
XMax = STATS_max_x
YMin = STATS_min_y
YMax = STATS_max_y
XRange = XMax-XMin
YRange = YMax-YMin
XBinCount = 20
YBinCount = 20
BinNo(x,y) = floor((y-YMin)/YRange*YBinCount)*XBinCount + floor((x-XMin)/XRange*XBinCount)
# do the binning
set table $Bins
plot $Data u (BinNo(,)):(1) smooth freq # with table
unset table
# prepare final data: BinNo, Sum, XPos, YPos
set print $FinalData
do for [i=0:N-1] {
set table $Data3
plot $Data u (BinNumber = BinNo(,),):(XPos = ,):(YPos = ,) every ::i::i with table
plot [BinNumber:BinNumber+0.1] $Bins u (BinNumber == ? (PointsInBin = ,) : NaN) with table
print sprintf("%g\t%g\t%g\t%g", XPos, YPos, BinNumber, PointsInBin)
unset table
}
set print
# plot data
set multiplot layout 2,1
set rmargin at screen 0.85
plot $Data u 1:2 w p pt 7 lc rgb "#BBFF0000" t "Data"
set xrange restore # use same xrange as previous plot
set yrange restore
set palette rgbformulae 33,13,10
set colorbox
# draw the bin borders
do for [i=0:XBinCount] {
XBinPos = i/real(XBinCount)*XRange+XMin
set arrow from XBinPos,YMin to XBinPos,YMax nohead lc rgb "grey" dt 1
}
do for [i=0:YBinCount] {
YBinPos = i/real(YBinCount)*YRange+YMin
set arrow from XMin,YBinPos to XMax,YBinPos nohead lc rgb "grey" dt 1
}
plot $FinalData u 1:2:4 w p pt 7 ps 0.5 lc palette z t "Density plot"
unset multiplot
### end of code
结果:
可能,比我之前的回答更好的方法如下。
在我 8 岁的电脑上,1000 点大约需要 2-3 分钟。您基本上可以为 3D 做同样的事情(参见
代码:
### density color plot 2D
reset session
N = 1000 # number of datapoints
Delta = 0.5 # half boxwidth
TimeStart = time(0.0)
# create some dummy datablock with some distribution
set table $Data
set samples N
plot '+' u (invnorm(rand(0))):(invnorm(rand(0))) w table
unset table
print sprintf("Data generated: %.3f sec",time(0.0)-TimeStart)
# end creating dummy data
TimeStart = time(0.0)
# put the datafile/dataset into arrays
stats $Data nooutput
RowCount = STATS_records
array ColX[RowCount]
array ColY[RowCount]
array ColC[RowCount]
do for [i=1:RowCount] {
set table $Dummy
plot $Data u (ColX[[=10=]+1]=,0):(ColY[[=10=]+1]=,0) with table
unset table
}
print sprintf("Data put into arrays: %.3f sec",time(0.0)-TimeStart)
# look at each datapoint and its sourrounding
do for [i=1:RowCount] {
# print sprintf("Datapoint %g of %g",i,RowCount)
x0 = ColX[i]
y0 = ColY[i]
# count the datapoints with distances <Delta around the datapoint of interest
set table $Occurrences
plot $Data u ((abs(x0-)<Delta) & (abs(y0-)<Delta) ? 1 : 0):(1) smooth frequency
unset table
# extract the number from $Occurrences which will be used to color the datapoint
set table $Dummmy
plot $Occurrences u (c0=,0):([=10=]) every ::1::1 with table
unset table
ColC[i] = c0
}
# put the arrays into a dataset again
set print $Data
do for [i=1:RowCount] {
print sprintf("%g\t%g\t%g",ColX[i],ColY[i],ColC[i])
}
set print
print sprintf("Duration: %.3f sec",time(0.0)-TimeStart)
set palette rgb 33,13,10
plot $Data u 1:2:3 w p ps 1 pt 7 lc palette z notitle
### end of code
将导致如下结果: