forked from OSGeo/grass-tutorials
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy paththematic_maps.qmd
More file actions
1465 lines (1004 loc) · 52.3 KB
/
thematic_maps.qmd
File metadata and controls
1465 lines (1004 loc) · 52.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
---
title: "Making Thematic Maps"
author: "Michael Barton"
date: 2025-06-25
date-modified: today
lightbox: true
engine: knitr
image: img_thematic/thumbnail.webp
format:
html:
embed-resources: true
toc: true
code-tools: true
code-copy: true
code-fold: false
page-layout: article
categories: [beginner, intermediate, GUI, raster, vector, thematic maps, legend]
description: This tutorial guides a user through multiple ways of creating thematic maps with raster and vector GIS data.
execute:
eval: false
copyright:
holder: Michael Barton
year: 2025
funding: "Creation of this tutorial was supported in part by US National Science Foundation grant FAIN 2303651."
---
Thematic maps are the most common form of analytical visualization done in GIS software. A thematic map uses color, or object shape or size, to represent geographic variation in some property, represented by categorical or numerical values in spatial data.
Most GIS software supports the creation of thematic maps from vector objects (points, lines, and areas). GRASS likewise enables the creation of thematic maps from vector data. It also supports the creation of thematic maps from rasters, which represent space as a grid of cells or pixels.
In this tutorial, we will explore the creation of thematic maps from both vector and raster geospatial data.
::: {.callout-note title="Dataset"}
This tutorial uses one of the standard GRASS sample data sets: nc_basic_spm_grass7. We will refer to place names in that data set, but it can be completed with any of the [standard sample data sets](https://grass.osgeo.org/download/data/) for any region. Keep in mind that the specific vector map attribute columns may not be available for a map from a different location, and you may need to use other attribute columns.
This tutorial is designed so that you can complete it using the **GRASS GUI**, GRASS commands from the **console or terminal**, or using GRASS commands in a **Jupyter Notebook** environment.
:::
::: {.callout-note title="Don't know how to get started?"}
If you are not sure how to get started with GRASS using its graphical user interface or using Python, checkout the tutorials [Get started with GRASS GUI](../get_started/fast_track.qmd) and [Get started with GRASS & Python in Jupyter Notebooks](../get_started/fast_track_grass_and_python.qmd).
:::
# Vector Thematic Maps
## Thematic maps in the Layer Manager
### Different colors and sizes to represent the value of a column
One of the easiest ways to create a thematic map is with the layer manager. In this method, each layer is a different theme. You can control the information displayed and vector object properties (e.g., color or size) for each layer using the vector properties tool, [d.vect](https://grass.osgeo.org/grass-stable/manuals/d.vect.html).
For example, we can display the *schools* vector points map—overlaying a vector map of streets to show where the schools are located—using different colors and sizes for different grade levels. The grade levels are recorded in the *GLEVEL* column of the *schools* attribute table by categorical values of **E** for elementary schools, **M** for middle schools, and **H** for high schools.
- To do this, you simply need to display the *streets* map, and then the *schools* map in three additional layers.
- For each layer, select a grade level to display and color and size of the symbol.
- For each layer, you will also want to specify a label that will show up in a legend.
::: {.panel-tabset group="language"}
#### GUI
**Streets layer**
1. Display the *streets* map in the layer manager. In the vector properties, set the feature (line) color to **grey** to make it easier to see the school symbols. Click the layer properties button (or right click on the layer) for a contextual menu and select "Zoom to selected map(s)".
2. Under Legend tab, set the "Label to display after symbol..." to **Wake Forest streets**.
**High school layer**
1. Display the *schools* map so it is above the *streets* map in the layer manager.
2. Open the vector properties tool for the *schools* map. Under the Selection tab, put the following query statement in the "Where" box. **GLEVEL='H'**. This will cause this layer to **only** display schools where the grade level is high school. You can also generate a query interactively by using the query builder button to the right of the entry box.
3. Click Apply (to display selected schools but not close the vector properties tool). Now you should only see the points representing high schools.
4. Under the vector properties Colors tab, set the "Area fill color" to **red**.
5. Under the vector properties Symbols tab, set the "Point and centroid symbol" to **basic/circle** and the "Symbol size" to **25**.
6. Under Legend tab, set the "Label to display after symbol..." to **high schools**.
7. Click OK. Now you will see high schools represented by large red circles.
**Middle school layer**
1. Display the *schools* map again in a new layer above the high schools layer in the layer manager.
2. In the vector properties for this new *schools* layer, enter **GLEVEL='M'** (for middle schools) in the Selection WHERE box, set the "Area fill color" to **yellow**, set the "Symbol size" to **20**, and the legend lable to **middle schools**.
3. Click OK. Now, along with high schools, you will see middle schools represented by slightly smaller, yellow circles.
**Elementary school layer**
1. Finally, display *schools* a third time in a new layer above the middle schools layer in the layer manager.
2. In the vector properties for this layer, enter **GLEVEL='E'** (for elementary schools) in the Selection WHERE box, set the "Area fill color" to **blue**, set the "Symbol size" to **15**, and the legend lable to **elementary schools**..
3. Click OK. Now, along with high schools and middle schools, you will also see elementary schools represented by even smaller, blue circles.
#### Command line
```{bash}
d.vect map=streets color=179:179:179:255 width=1 legend_label="Wake Forest streets"
d.vect map=schools where="GLEVEL='H'" color=0:29:57:255 fill_color=255:0:0:255 width=1 icon=basic/circle size=25 legend_label="high schools"
d.vect map=schools where="GLEVEL='M'" color=0:29:57:255 fill_color=255:255:0:255 width=1 icon=basic/circle size=20 legend_label="middle schools"
d.vect map=schools where="GLEVEL='E'" color=0:29:57:255 fill_color=0:0:255:255 width=1 icon=basic/circle size=15 legend_label="elementary schools"
```
#### Python
```{python}
gs.run_command("d.vect",
map="streets",
color="179:179:179",
width=1)
gs.run_command("d.vect",
map="schools",
where="GLEVEL = 'H'",
color="0:29:57",
fill_color="255:0:0",
width=1,
icon="basic/circle",
size=25,
legend_label="high schools")
gs.run_command("d.vect",
map="schools",
where="GLEVEL = 'M'",
color="0:29:57",
fill_color="255:255:0",
width=1,
icon="basic/circle",
size=20,
legend_label="middle schools")
gs.run_command("d.vect",
map="schools",
where="GLEVEL = 'E'",
color="0:29:57",
fill_color="0:0:255",
width=1,
icon="basic/circle",
size=15,
legend_label="elementary schools")
```
:::
Using different sizes (with larger symbols below smaller symbols), along with color, makes it easier to see where schools of different grade levels are co-located.

### Creating a legend
A legend can help you and other users better interpret the colored circles on the map. You can create a vector legend with the vector legend tool, [d.legend.vect](https://grass.osgeo.org/grass-stable/manuals/d.legend.vect.html), that you can access from the button bar at the top of the map display window.

The vector legend tool will create a legend with entries for all layers that are visible in a display. We can set a title and font, and control the background. But there are fewer options than the raster legend tool described in the section below for raster thematic maps.
::: {.panel-tabset group="language"}
#### GUI
1. Open the vector legend tool.
2. Under the title tab, set the "Legend title" to 'Schools by Grade Level' and the "Title font size" to 14.
3. Under the Background tab, check the "Display legend background" box.
4. Under the Font settings tab, set the "Font size" to 12.
5. Click OK to generate the legend.
#### Command line
```{bash}
d.legend.vect -b at=74.0,30 title="Schools by Grade Level" fontsize=12 title_fontsize=14
d.barscale -n at=70,10 length=10 units=kilometers segment=5 width_scale=2
```
#### Python
```{python}
gs.run_command("d.legend.vect",
at="74.0,30",
title="Schools by Grade Level",
fontsize=12,
title_fontsize=14,
flags="b")
gs.run_command("d.barscale",
at="70,10",
length=10,
units="kilometers",
segment=5,
width_scale=2,
flags="n")
```
:::
Here is the map with a legend. A scale bar has been added using the scale bar tool, [d.barscale](https://grass.osgeo.org/grass-stable/manuals/d.barscale.html), from the same button bar location as the vector legend tool.

::: {.callout-note title="Tip"}
If you want to regenerate this thematic map in the future, you can do so quickly using GRASS commands.
- Open the vector properties tool for each layer, click the Copy button and then paste the command generated into a text file.
- Do the same for the vector legend tool and the scale bar tool.
- This will create a file with the following sequence of commands (these can also be seen by clicking the "Command line" tab in this tutorial:
```
d.vect map=streets color=179:179:179 width=1 legend_label="Wake Forest streets"
d.vect map=schools where="GLEVEL='H'" color=0:29:57 fill_color=255:0:0 width=1 icon=basic/circle size=25 legend_label="high schools"
d.vect map=schools where="GLEVEL='M'" color=0:29:57 fill_color=255:255:0 width=1 icon=basic/circle size=20 legend_label="middle schools"
d.vect map=schools where="GLEVEL='E'" color=0:29:57 fill_color=0:0:255 width=1 icon=basic/circle size=15 legend_label="high schools"
d.legend.vect -b at=74.0,30 title="Schools by Grade Level" fontsize=12 title_fontsize=14
d.barscale -n at=70,10 length=10 units=kilometers segment=5 width_scale=2
```
You can paste these commands into the GRASS GUI console one at a time, in this order to recreate this map.
:::
You can use this same approach to create thematic area and line vector maps. Here is the *census* map showing household size in each census tract.

::: {.callout-note title="Commands with settings to generate map"}
d.vect map=census@PERMANENT where=HH_SIZE=0 color=0:29:57:255 fill_color=255:255:102:255 width=1 icon=basic/circle legend_label="no households"
d.vect map=census@PERMANENT where="HH_SIZE>0 AND HH_SIZE<2" color=0:29:57:255 fill_color=230:234:255:255 width=1 icon=basic/circle legend_label="< 2 people per household"
d.vect map=census@PERMANENT where="HH_SIZE>=2 AND HH_SIZE <= 4" color=0:29:57:255 fill_color=178:188:255:255 width=1 icon=basic/circle legend_label="2-4 people per household"
d.vect map=census@PERMANENT type=line,boundary,area,face where="HH_SIZE>4" color=0:0:0:255 fill_color=0:0:255:255 width=1 icon=basic/circle legend_label="> 4 people per household"
d.legend.vect -b at=75,25 title="Median Household Size" fontsize=12 title_fontsize=14
d.barscale -n at=70.5,10 length=4 units=kilometers segment=4 width_scale=2
:::
## Statistically Derived Thematic Maps
### Thematic mapping tool for choropleth maps
It can be useful to group continuous numerical values of a column into categories using various statistical measures of variability. The thematic mapping tool, [d.vect.thematic](https://grass.osgeo.org/grass-stable/manuals/d.vect.html), can do this using several statistical approaches, as well as supporting custom divisions. This tool only makes choropleth maps (i.e. using colors rather than symbol size for visualizing numerical values).
::::: grid
::: g-col-6
- The thematic mapping tool can be accessed from the special vector layer icon in the layer manager.
- It will create a new thematic vector layer.
:::
::: g-col-6
{fig-align="top"}
:::
:::::
#### Classification algorithms used in thematic mapping tool
| **Code** | \***Statistical grouping algorithm** |
|-:|:-------------------|
| int | Classes are grouped by equal divisions of the column values, the minimum to the maximum value. |
| std | Classes are divided by standard standard deviations below and above the mean. |
| qua | Classes are grouped into quantiles such that each group represents approximately an equal number of cases (rows of a column). |
| equ | Classes have equal probabilities of occurrence in a normal/Gaussian distribution. |
| dis | Classes are divided by natural breaks in the values of a column. The algorithm systematically searches for discontinuities in the slope of the cumulative frequencies curve of column values, by approximating this curve through straight line segments whose vertices define the class breaks. |
\**See the [v.class](https://grass.osgeo.org/grass-stable/manuals/v.class.html) manual for more detailed information.*
You can also select the number of classes to be calculated and specify custom breakpoints for classes instead of using the algorithms listed above for statistically calculated breaks.
We can use the thematic mapping tool to generate a new map of household size from the *census* map, where the categories are determined by standard deviation units rather than the arbitrary ones used above.
::: {.panel-tabset group="language"}
#### GUI
:::: grid
::: g-col-6
1. Open the thematic mapping tool to create a new thematic map layer.
2. Under the Required tab, enter *census* for the the source of the information to create the thematic map.
3. Select **HH_SIZE** for the column to be classified in the thematic map.
4. Select **4 colors** to use to visualize the standard deviation units. The example shown uses the interactive color picker (button to the right of the "Colors" entry box) to select:
- light blue (RGB 193:202:255:255) for 2-SD below the mean,
- dark blue (RGB 0:0:255:255) for 1-SD below the mean,
- dark red (RGB 251:2:7:255) for 1-SD above the mean, and
- light red (RGB 254:201:193:255) for 2-SD above the mean.
:::
::: g-col-6
{fig-align="right"}
:::
:::::
::::: grid
::: g-col-6
5. Under the Classes tab, select **std** for the standard deviation "Algorithm to use for classification", and **4** for the "Number of classes to define".
:::
::: g-col-6
{fig-align="right"}
:::
:::::
::::: grid
::: g-col-6
6. Under the Legend tab, check the "Create legend information and send to stdout" box. This will send legend rules to the terminal (not the GUI console) that we will use later.
7. Enter **Standard Deviation Units** in the "Thematic map title" box. This will become a subtitle in the legend.
8. Click OK.
:::
::: g-col-6
{fig-align="right"}
:::
:::::
9. Enter values for creating the legend as you did with the previous thematic map of households, and also enter **13** for the subtitle font size.
10. Keep the scale bar as you defined it previously, if you desire.
#### Command line
```{bash}
d.vect.thematic -l map=census column=HH_SIZE algorithm=std nclasses=4 colors="193:202:255:255,0:0:255:255,251:2:7:255,254:201:193:255" boundary_color=0:0:0:255 legend_title="Standard Deviation Units"
d.legend.vect -b at=76,40 title="Median Household Size" fontsize=12 title_fontsize=16 sub_fontsize=13
d.barscale -n at=72,21 length=4 units=kilometers segment=4 width_scale=2
```
#### Python
```{python}
gs.run_command("d.vect.thematic",
map="census",
column="HH_SIZE",
algorithm="std",
nclasses=4,
colors="193:202:255:255,0:0:255:255,251:2:7:255,254:201:193:255",
boundary_color="0:0:0:255",
legend_title="Standard Deviation Units",
flags="l")
gs.run_command("d.legend.vect",
at="76,40",
title="Median Household Size",
fontsize=12,
title_fontsize=14,
flags="b")
gs.run_command("d.barscale",
at="72,21",
length=10,
units="kilometers",
segment=5,
width_scale=2,
flags="n")
```
:::
And here is the map of census tracts classified by standard deviation units of household size.

### Customizing the legend
While this map is useful as it is, the legend could be improved somewhat. The legend items could be displayed with the values below the mean toward the bottom and above the mean toward the top. Also, it would be helpful to indicate which values were 1 and 2 SD above and below the mean.
There is no way to do this in the thematic mapping tool. But the it can be done through editing the legend rules that are automatically generated by the tool and used by the vector legend tool. This the information that appeared in the GRASS terminal when the thematic mapping tool was run. It should look like this:
```
||||||Standard Deviation Units
0.00 - 0.39|legend/area|5|ps|193:202:255|0:0:0|1|area|803
0.39 - 1.62|legend/area|5|ps|0:0:255|0:0:0|1|area|185
1.62 - 2.84|legend/area|5|ps|251:2:7|0:0:0|1|area|1189
2.84 - 7.00|legend/area|5|ps|254:201:193|0:0:0|1|area|360
```
These are a sequence of data fields separated by a *pipe* character **\|**. Each line of the legend is represented by one line of legend rules fields.
#### Key to legend rules
| **position**| **field** | **Explanation** |
|:-:|-:|:--------------------|
| 1 | label | Text that appears next to each color swatch in the legend. |
| 2 | symbol_name | Symbol used for the color swatch in the legend. |
| 3 | size | Size of the color swatch in the legend. |
| 4 | color_type | Order of the next two fields (positions 5 & 6) for the colors used for the color swatch. If the value of this field is **ps** (primary & secondary colors), the first field is for the fill and the second field is for the line/outline. If this field is **lf** (line & fill colors), the first field is the line/outline color and the second field is the fill color. Legends created by the thematic mapping tool use **ps** order, while legends created in other ways (e.g., as with the layer manager map) use **lf** order. Because this legend is created by the thematic mapping tool, these fields are fill color (position 5), followed by line color (position 6). |
| 5/6 | fill_color | Fill color of the color swatch. |
| 5/6 | feature_color | Line/outline color of the color swatch. |
| 7 | line_width | Width of the line/outline of the color swatch. |
| 8 | geometry_type | Vector object type being mapped. |
| 9 | feature_count | Count of cases (rows) in each category. |
You can edit these rules to change the appearance of your legend. To demonstrate, we will change the legend as proposed above.
::: {.panel-tabset group="language"}
#### GUI
::::: grid
::: g-col-6
1. Double click the vector legend to open the legend tool.
2. Under the In/Out tab, paste in the legend rules copied from the terminal.
:::
::: g-col-6
{fig-align="right"}
:::
:::::
3. Edit the rules so that they look like this:
```
||||||Standard Deviation Units
1SD to 2SD (2.84-7.00)|legend/area|5|ps|254:201:193|0:0:0|1|area|360
mean to 1SD (1.62-2.84)|legend/area|5|ps|251:2:7|0:0:0|1|area|1189
-1SD to mean (0.39-1.62)|legend/area|5|ps|0:0:255|0:0:0|1|area|185
-2SD to -1SD (0.00-0.39)|legend/area|5|ps|193:202:255|0:0:0|1|area|803
```
4. Optionally, you can save the legend rules to a text file by entering the path and name in the "Output csv file" entry box. That way, you can load them to use again by selecting them in the "Input legend file" box.
5. Click OK.
#### Command line
Save the text output to the terminal to a text file (e.g., named census_legend.txt). Edit it in the text file and then load it to use in the legend.
```{bash}
d.legend.vect -b at=76,40 title="Median Household Size" fontsize=12 title_fontsize=16 sub_fontsize=13 input="[your path]/census_legend.txt"
```
#### Python
Save the text output to the terminal to a text file (e.g., named census_legend.txt). Edit it in the text file and then load it to use in the legend.
```{python}
gs.run_command("d.legend.vect",
at="76,40",
title="Median Household Size",
fontsize=12,
title_fontsize=14,
sub_fontsize=13,
input="[your path]/census_legend.txt",
flags="b")
```
:::
Here is the thematic map with the customized legend

The thematic mapping tool can also make choropleth maps of vector points. For example, we can make a choropleth thematic map of elementary school capacity (*schools* vector points map) grouped by standard deviation units like the household size for census data. We only need to change a few settings.
::: {.panel-tabset group="language"}
#### GUI
1. Under the Required tab, change the "Name of the vector map" to ***schools*** and change the "Name of the attribute column" to **CORECAPCI**.
2. Under the Selection tab, enter **GLEVEL='E'** in the "WHERE" box to select elementary schools.
3. Under the Symbols tab, change the "Point and centroid symbol" to **basic/circle** and set the size to **15** points.
4. Under the Legend tab, change the "Legend symbol for areas" to **basic/circle** to match the display symbol.
5. Click OK.
6. Add a legend and scale bar as you did for the other maps. You can edit the legend as we did for the census households map if desired.
#### Command line
```{bash}
d.vect.thematic -l map=schools column=CORECAPACI algorithm=std nclasses=4 colors="193:202:255:255,0:0:255:255,251:2:7:255,254:201:193:255" where=GLEVEL='E' boundary_color=0:0:0:255 icon=basic/circle size=15 icon_area=basic/circle legend_title="Standard Deviation Units"
d.legend.vect -b at=73,40 title="Elementary School Capacity" fontsize=12 title_fontsize=16 sub_font=14
d.barscale -n at=73,10 length=10 units=kilometers segment=5 width_scale=2
```
#### Python
```{python}
gs.run_command("d.vect.thematic",
map="schools",
column="CORECAPACI",
algorithm="std",
nclasses=4,
colors="193:202:255:255,0:0:255:255,251:2:7:255,254:201:193:255",
where="GLEVEL='E'",
boundary_color="0:0:0:255",
icon="basic/circle",
size=15,
icon_area="basic/circle",
legend_title="Standard Deviation Units",
flags="l")
gs.run_command("d.legend.vect",
at="73,40",
title="Elementary School Capacity",
fontsize=12,
title_fontsize=14,
flags="b")
gs.run_command("d.barscale",
at="73,10",
length=10,
units="kilometers",
segment=5,
width_scale=2,
flags="n")
```
:::
Choropleth thematic map of elementary school capacities

## Thematic charts
### Thematic charts map
An alternative way to visualize quantitative geospatial information in GRASS is with thematic charts for vector points. The thematic charts tool, [d.vect.chart](https://grass.osgeo.org/grass-stable/manuals/d.vect.chart.html), can display pie or bar charts at point locations.
- Each pie segment or bar represents the value of a column for that point.
- The size of a pie chart can also represent the value of a column.
- In this way, the values of multiple columns can be visualized and compared across geographic space.
We can use thematic charts to display the equipment available at fire stations using the *firestations* vector map.
- The fire stations can have several different types of equipment, listed in different columns of the *firestations* attribute table: pumpers (*PUMPERS*), tankers (*TANKER*), pumper-tankers (*PUMPER_TAN*), and mini-pumpers (*MINI_PUMPE*).
- We can use the values in these columns to represent the proportion of each type of fire-fighting equipment in a thematic chart map.
- The **sum** of these columns can be used for the size of a pie chart, reflecting the total equipment inventory.
::: {.panel-tabset group="language"}
#### GUI
::::: grid
::: g-col-6
1. Open the thematic charts tool from the special vector layer icon in the layer manager.
:::
::: g-col-6
{fig-align="right"}
:::
:::::
::::: grid
::: g-col-6
2. Under the Required tab, enter *firestations* for "Name of vector map".
:::
::: g-col-6
{fig-align="right"}
:::
:::::
3. Enter the names of columns **PUMPERS,TANKER,PUMPER_TAN,MINI_PUMPE** (separated by commas, no spaces) into the "Attribute columns containing data" entry box.
::::: grid
::: g-col-6
4. Under the Chart properties tab, enter **pie** for the "Chart type".
5. Enter the equation **PUMPERS + TANKER + PUMPER_TAN + MINI_PUMPE** to use the total number of fire engines for the size of the pie charts.
6. Enter **15** in the "Scale for size" to get visually pleasing chart point sizes (15 X the sum of all the fire engines).
7. Enter **white** for the "Outline color" (255:255:255:255 as RGB and alpha/transparency).
8. Enter **4 colors** to represent the 4 columns that are being displayed in the chart.
- You can use the color picker button to the right of the entry box.
- Or you can enter them manually as RGB color values or one of the named GRASS colors (*red, orange, yellow, green, blue, indigo, violet, white, black, gray, brown, magenta, aqua, grey,cyan, purple*). The colors should be separated by commas with no spaces.
- The 4 colors used in this tutorial are: **255:0:0:255,0:0:255:255,204:102:255:255,254:204:102:255**.
9. Finally, make sure that the "Create legend information" box is checked under the Optional tab.
10. Click OK.
:::
::: g-col-6
{fig-align="right"}
:::
:::::
#### Command line
```{bash}
d.vect.chart -c -l map=firestations columns=PUMPERS,TANKER,PUMPER_TAN,MINI_PUMPE size_column=PUMPERS+TANKER+PUMPER_TAN+MINI_PUMPE size=-1 scale=15 outline_color=255:255:255:255 colors=255:0:0:255,0:0:255:255,204:102:255:255,254:204:102:255
```
#### Python
```{python}
gs.run_command("d.vect.chart",
map="firestations",
columns="PUMPERS,TANKER,PUMPER_TAN,MINI_PUMPE",
size_column="PUMPERS+TANKER+PUMPER_TAN+MINI_PUMPE",
size=-1,
scale=15,
outline_color="255:255:255:255",
colors="255:0:0:255,0:0:255:255,204:102:255:255,254:204:102:255",
flags="cl")
```
:::
Here is the thematic charts map of fire station capacities. It is underlain by a map of streets to show fire station localities, as we did with schools. It is clear that the smallest fire stations usually only have the same one kind of equipment. Slightly larger ones have the same one different kind of equipment. And the largest stations have the largest diversity of equipment. But what kind of equipment? We need a legend.

### Creating a legend for a thematic charts map
The thematic charts tool can send legend information to the terminal (not GUI console) like the thematic mapping tool. But it is not in the correct format to immediately use in vector legend.
Here is the legend information output by the thematic charts tool for this map:
```
1|PUMPERS|255:0:0
2|TANKER|0:0:255
3|PUMPER_TAN|204:102:255
4|MINI_PUMPE|254:204:102
```
We can use the procedures described above for a custom thematic map legend to make a legend for this thematic charts map. Here is are the legend rules we used previously:
```
||||||Standard Deviation Units
1SD to 2SD (2.84-7.00)|legend/area|5|ps|254:201:193|0:0:0|1|area|360
mean to 1SD (1.62-2.84)|legend/area|5|ps|251:2:7|0:0:0|1|area|1189
-1SD to mean (0.39-1.62)|legend/area|5|ps|0:0:255|0:0:0|1|area|185
-2SD to -1SD (0.00-0.39)|legend/area|5|ps|193:202:255|0:0:0|1|area|803
```
We can edit these to
- change the legend text,
- change the legend object to a circle for the colors,
- change the fill colors to match the ones output by the thematic charts tool,
- reference the objects plotted as points rather than areas, and
- delete the numbers of cases.
Here is what the new legend rules look like:
```
||||||Types of Fire Engines
pumpers|basic/circle|5|ps|255:0:0|0:0:0|1|area|
tankers|basic/circle|5|ps|0:0:255|0:0:0|1|area|
pumper-tankers|basic/circle|5|ps|204:102:255|0:0:0|1|area|
mini-pumpers|basic/circle|5|ps|254:204:102|0:0:0|1|area|
||||||(Chart sizes proportional to total number of fire engines)
streets|legend/line|5|lf|179:179:179:255|0:103:204|1|line|
```
Note that we've added a line for streets too.
::: {.panel-tabset group="language"}
#### GUI
1. As we did above, you can open the vector legend tool, add a main title (Fire Stations), set the font sizes (16 for title, 14 for sub title, 12 for legend font), and optionally turn on the background.
2. Paste the new legend rules into the text box under the In/Out tab.
3. You can optionally give it a path to save these rules to a file to be reused in the future.
4. Click Apply or OK.
#### Command line
Save the legend rules to a text file (e.g., named firestations_legend.txt) and then load it to use in the legend.
```{bash}
d.legend.vect -b at=68,30 title="Fire Stations" border_width=1 fontsize=12 title_fontsize=16 sub_fontsize=13 input="[your path]/firestations_legend.txt"
d.barscale -n at=70.0,8.0 length=10 units=kilometers segment=5 width_scale=2
```
#### Python
Save the legend rules to a text file (e.g., named firestations_legend.txt) and then load it to use in the legend.
```{python}
gs.run_command("d.legend.vect",
at="68,30",
title="Fire Stations",
fontsize=12,
title_fontsize=16,
sub_fontsize=14,
input="[your path]/firestations_legend.txt",
flags="b")
gs.run_command("d.barscale",
at="70.0,8.0",
length=10,
units="kilometers",
segment=5,
width_scale=2,
flags="n")
```
:::
The thematic charts map with a custom legend:

::: {.callout-note title="More legend customization"}
How could you add more lines to the custom legend to indicate the relationship between circle size and fire equipment inventory?
Remember that we scaled the circle size as 15x[total equipment]. The totals range from 0 to 7. So you could make new legend lines for 2, 4, & 6 equipment totals. To calculate the point size of each, simply multiply times 15, so that 2 engines = 30 pts, 4 engines = 60 pts, and 6 engines = 90 pts.
Then you can add 3 more lines to your custom legend like this one:
```
2 engines|basic/circle|30|ps|255:255:255|0:0:0|1|area|
```
You could also begin this new section with a subtitle:
```
||||||Total Fire Engines at Each Station
```
:::
The thematic charts tool can represent data as bar graphs instead of pie charts. Here is the same thematic charts map displayed as bar graphs. The "Size of chart" was set to **30**, the "Outline color" set to **black**, and the *symbol_name* in the legend file set back to **legend/area** for this map.

# Raster Thematic Maps
Raster thematic maps use color to represent varying land cover, land use, or terrain characteristics across a map. This can be characteristics like slope, represented in degrees, that varies continuously or like land cover, represented by areas of a map encoded with distinct categories.
## Rasters with continuous variation: terrain slope
Terrain slope is an example of a characteristic represented by numeric values (in degrees) that vary continuously across a landscape. A map of slope can be created from an elevation map using the [r.slope.aspect](https://grass.osgeo.org/grass-stable/manuals/r.slope.aspect.html) tool.
This will produce a map of continuously varying slope across the entire map. Colors can be assigned to raster cells according to their slope values to visualize areas of high and low slope. The slope that each color represents can be shown in a legend to help users interpret the map.
::: {.callout-note title="Modeling terrain in GRASS"}
To learn more about modeling and visualizing slope and other terrain characteristics in GRASS, see the[Visualizing and Modeling Terrain from DEMs in GRASS](..../terrain_and_DEMs/GRASS_terrain_pt.qmd) tutorial. For more information about rasters in GRASS, see [Raster data processing in GRASS](https://grass.osgeo.org/grass-stable/manuals/rasterintro.html#raster-map-operations).
:::
First, create a slope map from the *elevation* DEM map.
::::::::: {.panel-tabset group="language"}
#### GUI
::::: grid
::: g-col-6
1. Open r.slope.aspect tool from the Raster/Terrain analysis/Slope and aspect menu.
2. Set elevation raster layer as the "Name of input elevation raster map".
:::
::: g-col-6
{fig-align="right"}
:::
:::::
::::: grid
::: g-col-6
3. Enter name *slope* for "Name for output slope raster map".
4. Click Run.
:::
::: g-col-6
{fig-align="right"}
:::
:::::
#### Command line
```{bash}
r.slope.aspect elevation=elevation slope=slope
```
#### Python
```{python}
gs.run_command("r.slope.aspect",
elevation="elevation",
slope="slope")
```
:::::::::
Here is the resulting slope map.

### Selecting a color table
The default colors of the slope map we created vary from pale yellow to violet as slope changes from flat to steep. We can assign different *color tables* to represent variation in slope with different colors.
- For example, we could change the **intensity** of a color to represent slope: pale color for low slopes and intense color for steep slopes.
- Color tables can be assigned, and custom color tables defined, using the [r.colors](https://grass.osgeo.org/grass-stable/manuals/r.colors.html) module.
- Let's apply the *reds* color table to the slope map so that the slope is represented by the intensity of the red color.
::::::::: {.panel-tabset group="language"}
#### GUI
::::: grid
::: g-col-6
1. Select [r.colors](https://grass.osgeo.org/grass-stable/manuals/r.colors.html) tool from the Raster/Manage colors menu.
2. In the "Map" tab, select the *slope* map in the "Name of raster map(s)" entry box.
:::
::: g-col-6
{fig-align="right"}
:::
:::::
3. In the Define tab, select *reds* as the color table.
::::: grid
::: g-col-6
{fig-align="right"}
:::
::: g-col-6
{fig-align="left" width="60%"}
:::
:::::
4. Click Run.
#### Command line
```{bash}
r.colors map=slope color=reds
```
#### Python
```{python}
gs.run_command("r.colors",
map="slope",
color="reds")
```
:::::::::

Try out some other color tables. The original default color is the *slope* color table. Try the *gyr* (green to yellow to red) color table with *histogram equalization* checked. You can also make a custom color table, as we describe later in this tutorial.
### Creating a legend
A **legend** can help you determine what the range of values present in your map and how the colors correspond to these values. The raster [d.legend](https://grass.osgeo.org/grass-stable/manuals/d.legend.html) tool lets you easily make a highly informative legend for this map.
:::::::::::::::::::::::: {.panel-tabset group="language"}
#### GUI
::::: grid
::: g-col-6
The raster *d.legend* tool can be accessed from the display window tool bar. This tool has many options. We'll explore several of them.
:::
::: g-col-6
{fig-align="right"}
:::
:::::
::::: grid
::: g-col-6
1. Under the Input tab, enter *slope* as the "Name of raster map".
:::
::: g-col-6
{fig-align="right"}
:::
:::::
::::: grid
::: g-col-6
2. Under the Title tab, enter "Slope" as the "Legend title", and enter 14 as the "Title font size".
:::
::: g-col-6
{fig-align="right"}
:::
:::::
::::: grid
::: g-col-6
3. Under the Advanced tab, enter the degree symbol (°) or the word "deg" as "Units to display".
:::
::: g-col-6
{fig-align="right"}
:::
:::::
::::: grid
::: g-col-6
4. Under the Gradient tab, check the "Add histogram to smoothed legend" box. Also enter *0,10,20,30* in the "Specific values to draw ticks" to display these evenly spaced values as legend ticks.
:::
::: g-col-6
{fig-align="right"}
:::
:::::
::::: grid
::: g-col-6
6. Under the Font settings tab, enter 12 as the "Font size" for the legend.
:::
::: g-col-6
{fig-align="right"}
:::
:::::
::::: grid
::: g-col-6
6. Finally, under the Background tab, check the box to show the background.
7. Click OK to see the legend. You can reposition and resize the legend with a mouse or numerically under the Options tab.
:::
::: g-col-6
{fig-align="right"}
:::
:::::
#### Command line
- A legend can be generated using the [d.legend](https://grass.osgeo.org/grass-stable/manuals/d.legend.html) command.
- A scale bar and north arrow can be generated using the [d.barscale](https://grass.osgeo.org/grass-stable/manuals/d.barscale.html) command.
```{bash}
d.legend -d -b raster=slope title=Slope title_fontsize=14 units=° label_values=0,10,20,30 fontsize=12 border_color=0:0:0:255
d.barscale -n length=2 units=kilometers segment=5 bgcolor=none width_scale=2
```
#### Python
- A legend can be generated using the [d.legend](https://grass.osgeo.org/grass-stable/manuals/d.legend.html) command.
- A scale bar and north arrow can be generated using the [d.barscale](https://grass.osgeo.org/grass-stable/manuals/d.barscale.html) command.
```{python}