"nice looking" is obviously always a matter of taste, but I gave it a try. Regular gnuplot heatmaps need data on a grid, not a collection of random points. To get around this limitation I convert the data to an analytic expression and then use "splot". So assume that you start with data, that looks like this:
#x y v
3 2 1
5 6 0.2
8 5 0.5
I used to following python script to create a gnuplot script
#!/usr/bin/python
import sys
import os
import csv
def main(argv):
# check arguments
if len(argv) == 0:
print "Usage: heatmap.py inputfilename"
sys.exit(1)
# find and open input file
inputfilename = argv[0]
try:
inputfile = open(inputfilename)
except:
print "Can't read "+inputfilename
sys.exit(1)
# open output file carefully
outputfilemode = os.O_WRONLY | os.O_CREAT | os.O_EXCL
outputdir = os.path.dirname(os.path.abspath(inputfilename))
outputbasename = os.path.splitext(os.path.basename(inputfilename))[0]
outputfilename = os.path.join(outputdir, outputbasename+".gp")
try:
fd = os.open(outputfilename, outputfilemode, 0744)
except:
print "Can't create "+outputfilename
sys.exit(1)
outputfile = os.fdopen(fd, "w")
# write settings to output file
outputfile.write("#!/usr/bin/gnuplot\n")
outputfile.write("set terminal pngcairo size 800,600 enhanced\n")
outputfile.write("set output 'heatmap.png'\n")
outputfile.write("set palette defined ( 0 'black', 1 'red', 2 'yellow', 2.1 'white' )\n")
outputfile.write("set isosamples 100, 100\n")
outputfile.write("set style function pm3d\n")
outputfile.write("set pm3d map\n")
outputfile.write("unset colorbox\n")
outputfile.write("unset tics\n")
outputfile.write("set format x ''\n")
outputfile.write("set format y ''\n")
outputfile.write("set lmargin at screen 0\n")
outputfile.write("set rmargin at screen 1\n")
outputfile.write("set bmargin at screen 0\n")
outputfile.write("set tmargin at screen 1\n")
# intensity of the dot depending on value
outputfile.write("w(v)=v\n")
# size of the dot depending on value
outputfile.write("s(v)=sqrt(v)\n")
# collect points to plot from dat file
p = []
dat_xmin = float('inf')
dat_xmax = float('-inf')
dat_ymin = float('inf')
dat_ymax = float('-inf')
reader = csv.reader(inputfile, delimiter=" ")
for r in reader:
if r[0].startswith("#"):
continue
x = float(r[0])
y = float(r[1])
v = float(r[2])
dat_xmin = min(dat_xmin, x)
dat_xmax = max(dat_xmax, x)
dat_ymin = min(dat_ymin, y)
dat_ymax = max(dat_ymax, y)
p.append("w("+str(v)+")/exp(((x-("+str(x)+"))**2 + (y-("+str(y)+"))**2)/s("+str(v)+"))")
#calculate range
plot_xmin = dat_xmin - 0.2*(dat_xmax - dat_xmin)
plot_xmax = dat_xmax + 0.2*(dat_xmax - dat_xmin)
plot_ymin = dat_ymin - 0.2*(dat_ymax - dat_ymin)
plot_ymax = dat_ymax + 0.2*(dat_ymax - dat_ymin)
# write plot command
outputfile.write("splot ")
outputfile.write("["+str(plot_xmin)+":"+str(plot_xmax)+"]["+str(plot_ymin)+":"+str(plot_ymax)+"] ")
outputfile.write("+".join(p))
outputfile.write( " notitle\n")
# close output file
outputfile.close()
print "Done. Now run "+outputfilename
if __name__ == "__main__":
main(sys.argv[1:])
Running the resulting gnuplot script generates the following image
Color palette, size, and relative intensity of the dots can be tweaked but this should at least give you an idea how to generate heatmaps.
answered
17 Dec '13, 23:08
petschge
8.3k●21●73●98
accept rate:
21%
Can’t you make one or a script based on OSM yourself ? It seems to me that’s not a specific OSM question, besides that you want OSM data as basement. Feel free to do so.