From: Allin C. <cot...@wf...> - 2020-04-16 13:56:28
|
On Tue, 14 Apr 2020, Ethan A Merritt wrote: > On Monday, 13 April 2020 13:14:54 PDT Allin Cottrell wrote: >> On Fri, 6 Mar 2020, Ethan A Merritt wrote: >> >> [a propos Manfred Schwarb's suggestion of using GeoJSON files >> for geographic plotting in gnuplot] >> >>> Good call. Geojson looks quite promising. >>> A real parser should be easy, but even a quick pass through sed >>> or a text editor makes it usable. >>> I have posted a proof-of-principle example using US state boundary >>> data from a sample file on the geojson development site: >>> >>> http://skuld.bmsc.washington.edu/people/merritt/gnuplot/ >> >> Thanks for the example, Ethan. >> >> I've recently returned to this issue, exploring the shapefiles >> option. I've written some relevant utilities in C, designed to link >> against Frank Warmerdam's lipshape. (I'll be happy to share these >> once they're better tested.) With their help I've managed to create >> quite a nice map of the US states, colorized by state population >> levels. See >> http://ricardo.ecn.wfu.edu/pub/gretl/datamaps/statepop.png . >> >> But the method I'm using for the colorization is clunky and I'm sure >> it can be improved upon. Here's my input file: >> >> <gnuplot> >> set term pngcairo size 660,400 >> set output 'statepop.png' >> set linetype 1 lc rgb "white" lw 1 >> >> set palette model HSV file 'statepop.hsv' >> set cbrange [0:50] >> unset colorbox >> >> set xrange [95:210] >> set yrange [-175:-135] >> set noxtics >> set noytics >> set border 0 >> unset key >> >> plot for [i=0:*] 'merc.dat' index i with filledcurves \ >> fc palette cb i, 'merc.dat' with lines lt 1 >> </gnuplot> >> >> In the above, 'merc.dat' contains the state outlines from the .shp >> file. The population data get into the picture via the pre-processed >> 'statepop.hsv'. To produce this (with its shades of blue) I ran a >> loop across the states using H = 229/360, V = 93/100, and S[i] = >> population of state i divided by the max population value. >> >> Any suggestions on the best way to do the colorization within >> gnuplot? And also, perhaps, how to discretize it (by decile for >> instance)? Is there a way to replace >> >> fc palette cb i >> >> with something like >> >> fc palette cb <function of i and the data to be colorized> > > Assuming you can get the state's population from somewhere > (maybe the header of the data block in the outlines file?) > the palette need not be involved. In general the data one wants to represent via color on a map will not be present in the outlines file; they'll come from some other source (as in my population data). > blue = 0x000044 > white = 0xffffff > color(i) = pop(i)/maxpop * blue + (maxpop-pop(i))/maxpop * white > > If you use your array S[], that becomes > color(i) = S[i] * blue + (1.0-S[i]) * white > > Then you can plot using the color directly > > plot for [i=0:*] 'merc.dat' index i using 1:2:(color(i)) with filledcurves \ > fc rgb variable Nice, thanks. Using a gnuplot array for the "extra" data is clearly a good solution. My only problem is that I'm trying to come up with something that works for gnuplot >= 5.0 (and arrays are new in 5.2). I've found one alternative to my original approach: In preparing the data for gnuplot, I append a third column after the coordinate pairs for the vertices of the outlines. The values in this column repeat the population (or whatever) value for each entity. So now I can do something like: set cbrange [0:1] set palette defined (0 'white', 1 'steelblue') ... plot for [i=0:*] 'states.dat' index i with filledcurves \ fc palette, 'states.dat' using 1:2 with lines where a little slice of one of the states in 'states.dat' looks like this: # longitude, latitude, popratio -85.799227 41.763535 0.25275361 -86.068302 41.764628 0.25275361 -86.234565 41.764864 0.25275361 -86.525181 41.765540 0.25275361 -86.834829 41.765504 0.25275361 Allin Cottrell |