How to generate random coordinates for pattern fill?

Here is what I’m trying to achieve:

When plotting land classes on a map one often needs a pattern to fill a certain area. Therefore I need to place symbols (tufts of gras, sand dunes, trees, …) in an pseudo-random pattern where the distance between neighbouring points is not smaller than j (to avoid overlapping symbols) but also not larger than k (to comply with the specification I have to follow).

I try to avoid using raster graphics (-Gp) for this as the resolution is too low and I need the flexibility custom symbols offer e.g. sand dunes need to be oriented to the prevailing wind direction.

My plan is to generate a set of coordinates which I can use to place my symbols and then use a mask to have it only visible where I need it. My problem: How do I generate such a set of coordinates which cover the whole plot while obeying the constraints j & k?

Do you have a good starting point for me?

  • Make a grid with grdmath with -I satisfying the condition j.
  • Convert it to x,y (throw away z)
  • Add random noise to x,y such that it complies with condition k
  • Lots of good luck doing this in bash

Hi @Joaquim, thank you for your giving me some hints. I experimented quite a bit with it but I got stuck. Here is what I got so far:

I used a base grid in a pattern as seen in panel a) in 0.25 zoomed (first row). The columns are 0.5 units apart in x and y direction. Then I added some noise in x and y direction. Here I present two different increments:

  • +/-0.25
  • +/-0.15

Panel a) (except for the first row titled 0.25 zoomed) shows the built-in -Gp31 pattern as a reference.

Panel b) is the result of my experimentation with a symbol trying to mimic the built-in pattern

Panel c) is the comparison between the base grid (panel a) in first row) and the grid with the added noise.

The problems I observed:

  • Width the larges increment of +/-0.25 the points can get too close together and also further apart than I want it. See area around (5.5|6) for further apart; (5|0) and (9|4) for too close in 0.25 zoomed panels b) & c).
  • The smaller the increment, the larger the areas where there can’t be any point thus leading to a more geometric pattern which I want to avoid:

A point can fall only in the red areas. The smaller I make the possible deviation the more geometric the pattern becomes.

Do you have another idea how I can get a more random grid pattern (similar to -Gp31) while still maintaining max and min distances between points?

Not sure. But gmt spatial -Aa can be used to replace neighbors that are too close with their average. So that could help with your case at (9,4). If you could select parameters so that you dont get too many or any that are too far apart then perhaps this could work.

Just in case this is a shorter path to getting those random x,y coordinates, here is what I tried:

gmt grdmath -R0/10/0/10 -I1 0 0.25 NRAND X ADD = x.grd 0 0.25 NRAND Y ADD = y.grd
gmt grd2xyz x.grd -o2  > x
gmt grd2xyz y.grd -o2 > y
gmt convert -A x y | gmt plot -R0/10/0/10 -JX10c -Sc3p -Gred -B -pdf t

Hi @pwessel,

your way is way more elegant. Thank you for the tip with gmt spatial – it helped a lot with points too close together. But the empty areas remain (and occasionally got bigger) and I get some worm structures? I don’t really understand why some pairs and some triplets got deleted (panel c)) creating empty spaces.

gmt grdmath -R0/20/0/20 -I0.5 \
  0 0.25 NRAND X ADD = x.grd \
  0 0.25 NRAND Y ADD = y.grd
gmt grd2xyz x.grd -o2  > x.txt
gmt grd2xyz y.grd -o2 > y.txt
gmt convert -A x.txt y.txt > xy.txt 

gmt begin random_points_8 png
  gmt subplot begin 2x2 -M10p/40p -A -Fs10c -JX10c -R0/20/0/20
    gmt subplot set
      gmt plot xy.txt -Sc0.125c -Gred -B -B+t"base grid"
    gmt subplot set
      gmt spatial -Aa0.3 xy.txt > xy_free.txt
      gmt plot xy_free.txt -Sc0.125c -Gblue -B -B+t"tidied grid"
    gmt subplot set
      gmt plot xy.txt -Sc0.125c -Gred@50 -B
      gmt plot xy_free.txt -Sc0.125c -Gblue@50 -B -B+t"both grids together"
  gmt subplot end
gmt end show

Some further experimentation showed an interesting pattern. I’m not quite sure if it is supposed to clump like this in the middle when using gmt spatial -Aa. As far as I understand it – shouldn’t the blue points spread evenly across the plot?

Code to play with:

gmt grdmath -R0/100/0/100 -I0.5 \
  0 0.25 NRAND X ADD = x.grd \
  0 0.25 NRAND Y ADD = y.grd
gmt grd2xyz x.grd -o2  > x.txt
gmt grd2xyz y.grd -o2 > y.txt
gmt convert -A x.txt y.txt > xy.txt 

gmt begin random_points_8 jpg
  gmt subplot begin 2x2 -M10p/40p -A -Fs10c -JX10c -R0/100/0/100
    gmt subplot set
      gmt plot xy.txt -Sc0.0625c -Gred -B -B+t"base grid"
    gmt subplot set
      gmt spatial -Aa0.5 xy.txt > xy_free.txt
      gmt plot xy_free.txt -Sc0.125c -Gblue -B -B+t"tidied grid"
    gmt subplot set
      gmt plot xy.txt -Sc0.125c -Gred@50 -B
      gmt plot xy_free.txt -Sc0.125c -Gblue@50 -B -B+t"both grids together"
  gmt subplot end
gmt end show

I am guessing that is because of your boundaries. If you do the math on -50/150 but only show 0/100 I get those effects go away.

@pwessel thank you for the explanation. I wasn’t aware that there might be a problem at boundaries. I switched to 1/3 buffer on all sides.

Do you have an explanation for the vanishing points (green circles) as well? Most of them seem to have an easy solution?

Code to play with:

Dataset used for above plots: xy.txt.zip (26.7 KB)

gmt begin random_points_9 jpg
  gmt subplot begin 1x3 -M10p/40p -A -Fs10c -JX10c -R0/10/0/10
    gmt subplot set
      gmt plot xy.txt -Sc0.125c -Gred -B -B+t"base grid"
    gmt subplot set
      gmt spatial -Aa0.5 xy.txt > xy_free.txt
      gmt plot xy_free.txt -Sc0.125c -Gblue -B -B+t"tidied grid"
    gmt subplot set
      gmt plot xy.txt -Sc0.125c -Gred@50 -B
      gmt plot xy_free.txt -Sc0.125c -Gblue@50 -B -B+t"both grids together"
  gmt subplot end
gmt end show

Odd, but sorry, no good ideas comes to mind. I guess you played with the -Aa argument (you used 0.5 I think).

Do you have an example of what you would like to obtain?

Yes, I played with -Aa quite a bit, @pwessel. As long as the increment is < -I I get that funny behaviour. In the example case I used -Aa = -I / 2 = 0.5. Interestingly there are some new points (light blue) without obviously replaced points (red) nearby as well. One example is in panel c) about half way between the two lower left green circles (light blue dot).

Hi @joaquim, I basically want to create a configurable, infinite pattern -Gp31 which has no discernible pattern but at the same time has a uniform appearance. Configurable in this context means I can specify max and min distance between points. This is important to me as I want to place custom symbols at those points. The symbols are not allowed to overlap but also can’t be more than a specified max distance apart.

Yes, I understood that but was thinking in a real map example produced by someone else.

Perhaps another idea to try is to generate more x,y inside each cell and use block* to find the mean position. This number can not be high to avoid that the mean position falls over the cell center.

I like the blockmean idea. While at it, try blockmedian for less averaging.

Oh, I misunderstood you there, @Joaquim – my apologies. Some examples:


Sand (left side) and Sand Dunes (right side) on Operational Navigation Chart ONC H-4 published by Defense Mapping Agency – USA.


Sand (left side) and crescent-shaped dunes (right side) on current Phoenix Sectional Aeronautical Chart published by the Federal Aviation Administration – USA


Swamp and Marsh on current Caribbean 1 VFR Aeronautical Chart published by the Federal Aviation Administration – USA

The charts are all following the design guidelines laid down in MIL-STD-2410 Appendix D “Area Patterns”.

Ai ai, that Gran Desierto is crazy. The sand grains however show some circular patterns. I made me think on Huygen’s principle for making waves after punctual sources.

@Joaquim you think of intersecting several wave patterns and using the crossing points as coordinates? The dunes aren’t that difficult – just custom symbols rotated to the local prevailing wind direction.

That sounds too complicated. I mentioned it because I seem to see the points distributing along arc-circles of varying length.

Ok, sand issue solved (almost). I knew I was seeing something circular.

See the last figures of this paper. That lead me to these wiki pages but was not understanding on how to create these


But then I found a clever guy with this Matlab contribution. It’s almost what you want, except the center that is too crowded.
Summarized it in this Julia Notebook.

Now Paul can do his gmtmath magick.

Wow, that is a great find and very beautiful! I dug around a bit in the sources you kindly provided and found

Vogel, H (1979). “A better way to construct the sunflower head”. Mathematical Biosciences 44 (44): 179–189. doi:10.1016/0025-5564(79)90080-4.

Vogel’s work was used by Jeffrey Rosenbluth and has no crowding in the center:
Sunflower.big

An interactive version was made by Jacopo Notarstefano.

I’m just not sure if this really is the reason for this circular pattern you can see in the sand in the examples I provided. The sand has no definite center where the dots radiate out from.

I’m under the impression that the pattern might be from the artist dotting the area pattern by hand on the film master screen used for reproduction. So maybe it is more an example of the human limitation to make random patterns without introducing tidiness?