r.colors.stddev.py 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. #!/usr/bin/env python3
  2. ############################################################################
  3. #
  4. # MODULE: r.colors.stddev
  5. # AUTHOR: M. Hamish Bowman, Dept. Marine Science, Otago University,
  6. # New Zealand
  7. # Converted to Python by Glynn Clements
  8. # PURPOSE: Set color rules based on stddev from a map's mean value.
  9. #
  10. # COPYRIGHT: (c) 2007,2009-2010 Hamish Bowman, and the GRASS Development Team
  11. # This program is free software under the GNU General Public
  12. # License (>=v2). Read the file COPYING that comes with GRASS
  13. # for details.
  14. #
  15. #############################################################################
  16. # %module
  17. # % description: Sets color rules based on stddev from a raster map's mean value.
  18. # % keyword: raster
  19. # % keyword: color table
  20. # %end
  21. # % option G_OPT_R_MAP
  22. # %end
  23. # %flag
  24. # % key: b
  25. # % description: Color using standard deviation bands
  26. # %end
  27. # %flag
  28. # % key: z
  29. # % description: Force center at zero
  30. # %end
  31. import os
  32. import atexit
  33. import grass.script as gscript
  34. from grass.script.utils import decode
  35. def z(n):
  36. return mean + n * stddev
  37. def cleanup():
  38. if tmpmap:
  39. gscript.run_command(
  40. "g.remove", flags="f", type="raster", name=tmpmap, quiet=True
  41. )
  42. def main():
  43. global tmpmap
  44. tmpmap = None
  45. map = options["map"]
  46. zero = flags["z"]
  47. bands = flags["b"]
  48. if not zero:
  49. s = gscript.read_command("r.univar", flags="g", map=map)
  50. kv = gscript.parse_key_val(decode(s))
  51. global mean, stddev
  52. mean = float(kv["mean"])
  53. stddev = float(kv["stddev"])
  54. if not bands:
  55. # smooth free floating blue/white/red
  56. rules = "\n".join(
  57. [
  58. "0% blue",
  59. "%f blue" % z(-2),
  60. "%f white" % mean,
  61. "%f red" % z(+2),
  62. "100% red",
  63. ]
  64. )
  65. else:
  66. # banded free floating black/red/yellow/green/yellow/red/black
  67. # reclass with labels only works for category (integer) based maps
  68. # r.reclass input="$GIS_OPT_MAP" output="${GIS_OPT_MAP}.stdevs" <<
  69. # EOF
  70. # >3 S.D. outliers colored black so they show up in d.histogram w/ white background
  71. rules = "\n".join(
  72. [
  73. "0% black",
  74. "%f black" % z(-3),
  75. "%f red" % z(-3),
  76. "%f red" % z(-2),
  77. "%f yellow" % z(-2),
  78. "%f yellow" % z(-1),
  79. "%f green" % z(-1),
  80. "%f green" % z(+1),
  81. "%f yellow" % z(+1),
  82. "%f yellow" % z(+2),
  83. "%f red" % z(+2),
  84. "%f red" % z(+3),
  85. "%f black" % z(+3),
  86. "100% black",
  87. ]
  88. )
  89. else:
  90. tmpmap = "r_col_stdev_abs_%d" % os.getpid()
  91. gscript.mapcalc("$tmp = abs($map)", tmp=tmpmap, map=map)
  92. # data centered on 0 (e.g. map of deviations)
  93. info = gscript.raster_info(tmpmap)
  94. maxv = info["max"]
  95. # current r.univar truncates percentage to the base integer
  96. s = gscript.read_command(
  97. "r.univar", flags="eg", map=map, percentile=[95.45, 68.2689, 99.7300]
  98. )
  99. kv = gscript.parse_key_val(decode(s))
  100. stddev1 = float(kv["percentile_68_2689"])
  101. stddev2 = float(kv["percentile_95_45"])
  102. stddev3 = float(kv["percentile_99_73"])
  103. if not bands:
  104. # zero centered smooth blue/white/red
  105. rules = "\n".join(
  106. [
  107. "%f blue" % -maxv,
  108. "%f blue" % -stddev2,
  109. "0 white",
  110. "%f red" % stddev2,
  111. "%f red" % maxv,
  112. ]
  113. )
  114. else:
  115. # zero centered banded black/red/yellow/green/yellow/red/black
  116. # >3 S.D. outliers colored black so they show up in d.histogram w/ white background
  117. rules = "\n".join(
  118. [
  119. "%f black" % -maxv,
  120. "%f black" % -stddev3,
  121. "%f red" % -stddev3,
  122. "%f red" % -stddev2,
  123. "%f yellow" % -stddev2,
  124. "%f yellow" % -stddev1,
  125. "%f green" % -stddev1,
  126. "%f green" % stddev1,
  127. "%f yellow" % stddev1,
  128. "%f yellow" % stddev2,
  129. "%f red" % stddev2,
  130. "%f red" % stddev3,
  131. "%f black" % stddev3,
  132. "%f black" % maxv,
  133. ]
  134. )
  135. gscript.write_command("r.colors", map=map, rules="-", stdin=rules)
  136. if __name__ == "__main__":
  137. options, flags = gscript.parser()
  138. atexit.register(cleanup)
  139. main()