Ćwiczenie 3 - Palety kolorów¶
In [1]:
import pandas as pd
import geopandas as gpd
import matplotlib as mpl
import matplotlib.pyplot as plt
import matplotlib.colors as clt
import libpysal as ps
/tmp/ipykernel_11476/1019557585.py:1: DeprecationWarning: Pyarrow will become a required dependency of pandas in the next major release of pandas (pandas 3.0), (to allow more performant data types, such as the Arrow string type, and better interoperability with other libraries) but was not found to be installed on your system. If this would cause problems for you, please provide us feedback at https://github.com/pandas-dev/pandas/issues/54466 import pandas as pd
In [2]:
#Wczytanie danych
counties_attr = gpd.read_file("data/counties_attr_5070.gpkg")
counties_attr.plot()
Out[2]:
<Axes: >
In [3]:
counties_attr.head()
Out[3]:
county_code | STATEFP | COUNTYFP | COUNTYNS | AFFGEOID | GEOID | NAME_cnt | LSAD | ALAND | AWATER | ... | POVERTY_UNDER1 | INSURED_UNDER65 | VACANT_HOUSES | MEDIAN_HOUSEVALUE | POP_DENS | MEDIAN_INCOME_DIF | POP_DENS_DIF | HIGH_EDUCATION | IQR_HOUSEVALUE | geometry | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 39131 | 39 | 131 | 01074078 | 0500000US39131 | 39131 | Pike | 06 | 1140324458 | 9567612 | ... | 0.206823 | 0.863582 | 0.129658 | 97800.0 | 24.609268 | 0.035057 | -0.012355 | 0.122750 | 91900.0 | MULTIPOLYGON (((1078952.714 1868952.030, 11275... |
1 | 46003 | 46 | 003 | 01266983 | 0500000US46003 | 46003 | Aurora | 06 | 1834813753 | 11201379 | ... | 0.062066 | 0.926331 | 0.138659 | 69000.0 | 1.479945 | 0.142150 | 0.002201 | 0.206253 | 90400.0 | MULTIPOLYGON (((-224564.942 2330413.103, -1864... |
2 | 55035 | 55 | 035 | 01581077 | 0500000US55035 | 55035 | Eau Claire | 06 | 1652211310 | 18848512 | ... | 0.145896 | 0.906677 | 0.065005 | 153200.0 | 60.983448 | 0.056816 | 0.029863 | 0.307505 | 103000.0 | MULTIPOLYGON (((343110.954 2437541.757, 400496... |
3 | 48259 | 48 | 259 | 01383915 | 0500000US48259 | 48259 | Kendall | 06 | 1715747531 | 1496797 | ... | 0.061375 | 0.890025 | 0.106320 | 285900.0 | 22.716632 | 0.067041 | 0.156023 | 0.393330 | 283900.0 | MULTIPOLYGON (((-280935.991 789039.934, -24897... |
4 | 40015 | 40 | 015 | 01101795 | 0500000US40015 | 40015 | Caddo | 06 | 3310745124 | 30820525 | ... | 0.207682 | 0.732646 | 0.215021 | 79400.0 | 8.831189 | 0.053571 | 0.003639 | 0.160735 | 89800.0 | MULTIPOLYGON (((-235706.133 1391786.040, -2078... |
5 rows × 50 columns
Palety kolorów¶
Więcej informacji:
- https://matplotlib.org/stable/gallery/color/colormap_reference.html
- https://github.com/jarekj71/zaawansowana_wizualizacja_danych/tree/master/05_kolory
- https://matplotlib.org/stable/users/explain/colors/colormaps.html
Mapy kolorów¶
- wbudowane mapy kolorów https://matplotlib.org/stable/gallery/color/colormap_reference.html
- mapy dyskretne (Listed)
- mapy ciągłe (LinearSegmented)
Paleta kolorów dla zmiennej skategoryzowanej¶
Zmienna RUCC_2013 zawiera kody wprowadzone przez Rural-Urban Continuum Codes. Klasyfikacja ta wskazuje czy hrabstwo (counties) położone jest w obszarze metropolitarnym czy poza oraz jaka jest liczba ludności w obszarach zurbanizowanych.
In [4]:
counties_attr.plot(column = "RUCC_2013",
cmap="Set1",
legend=True,
legend_kwds={"label": "RUCC", "orientation": "horizontal"})
Out[4]:
<Axes: >
Prypisanie własnych kolorów do zmiennej skategoryzowanej¶
In [5]:
#assign colors to categories
colors = {
"1": "brown",
"2": "red",
"3": "orange",
"4": "darkgreen",
"5": "lightgreen",
"6": "purple",
"7": "pink",
"8": "blue",
"9": "lightblue"
}
#create color scheme
cmap = clt.ListedColormap(list(colors.values()))
#plot map
counties_attr.plot(column = "RUCC_2013",
cmap=cmap,
legend=True,
legend_kwds={"label": "RUCC", "orientation": "horizontal"})
Out[5]:
<Axes: >
Paleta kolorów dla zmiennej ciągłej¶
In [6]:
counties_attr.plot(column = "WHITE",
legend=True,
legend_kwds={"label": "Percent of Whites", "orientation": "horizontal"})
Out[6]:
<Axes: >
In [7]:
#przypisanie palety
counties_attr.plot(column = "WHITE",
cmap = "YlOrBr",
legend=True,
legend_kwds={"label": "Percent of Whites", "orientation": "horizontal"})
Out[7]:
<Axes: >
Zadanie samodzielne¶
- Wykonać mapę pokazująca procent czarnych (kolumna BLACK)
- Wybrać dowolną paletę z wbudowanych.
Palety rozbieżne (Diverging colors)¶
In [8]:
#normy vcenter=0
counties_attr.plot(column = "POP_DENS_DIF",
cmap = "bwr",
norm=clt.CenteredNorm(halfrange=0.7),
legend=True,
legend_kwds={"label": "Difference in population density", "orientation": "horizontal"})
Out[8]:
<Axes: >
In [9]:
counties_attr.plot(column = "POP_DENS_DIF",
cmap = "bwr",
legend=True,
legend_kwds={"label": "Difference in population density", "orientation": "horizontal"})
Out[9]:
<Axes: >
Normalizacja kolorów¶
In [10]:
counties_attr.plot(column = "BLACK",
cmap = "YlOrBr",
legend=True,
legend_kwds={"label": "Percent of Blacks", "orientation": "horizontal"})
Out[10]:
<Axes: >
In [11]:
norm = mpl.colors.Normalize(vmin=0, vmax=1)
counties_attr.plot(column = "BLACK",
cmap = "YlOrBr",
norm = norm,
legend=True,
legend_kwds={"label": "Percent of Blacks", "orientation": "horizontal"})
Out[11]:
<Axes: >
Norma dyskretna - Kategoryzacja kolorów dla zmiennej ciągłej¶
In [12]:
breaks = [0, 0.25, 0.5, 0.75, 1]
norm = clt.BoundaryNorm(boundaries=breaks, ncolors=256)
counties_attr.plot(column = "BLACK",
cmap = "YlOrBr",
norm = norm,
legend=True,
legend_kwds={"label": "Percent of Blacks", "orientation": "horizontal"})
Out[12]:
<Axes: >
Metody podziału danych na klasy - biblioteka PySAL¶
Więcej informacji
Równa liczba (kwantyle) (ang. equal counts - quantiles)¶
- Podział wyznaczony kwantylami polega podziale na klasy o równej liczebności (liczba pól odniesienia w każdym przedziale będzie taka sama)
- Podział prowadzi do klas o różnym zakresie danych (np. 1-5, 5-10, 10-100).
- Podział taki może być mylący; może powodować, że obserwacje o bardzo podobnych wartościach znajdą się w różnych klasach lub obserwacje o różnych wartościach będą przyporządkowane do tej samej klasy.
- Stosowany do równomiernie rozłożonych danych i do danych w skali porządkowej.
- Przedziały obliczane są biorąc całkowitą liczbę wartości danych i dzieląc przez liczbę pożądanych klas, aby uzyskać równą liczbę obserwacji danych w każdej klasie.
In [13]:
counties_attr.plot(column = "WHITE",
cmap = "YlOrBr",
k = 5,
scheme="quantiles",
legend=True)
Out[13]:
<Axes: >
Równe przedziały (equal intervals)¶
- Podział na klasy o równej rozpiętości (np. 0-5, 5-10, 10-15);
- Stosowany w sytuacji, gdy użytkownik dobrze zna zakres danych
- Stosowany gdy dane są rozłożone w całym zakresie.
- Nie należy stosować tej metody do danych o rozkładzie skośnym lub w przypadku występowania wartości odstających.
- Przydatny do wizualizacji danych wyrażonych w procentach.
- Przedziały klas obliczane biorąc najwyższą wartość danych pomniejszoną o najniższą wartość danych i dzieląc przez liczbę klas pożądanych w celu uzyskania przerw w klasach w równoważnych odstępach czasu.
In [14]:
counties_attr.plot(column = "WHITE",
cmap = "YlOrBr",
k = 5,
scheme="equal_interval",
legend=True)
Out[14]:
<Axes: >
Naturalny podział (ang. natutal breaks, Jenks)¶
- polega na pogrupowaniu wartości podobnych, tak aby granice klas dzieliły wartości różne
- podział wynikający z naturalnego rozkładu zmiennej;
- podział zapewniający minimalną zmienność wewnątrz klasy oraz maksymalną zmienność między klasami.
- Dobrze się sprawdza przy każdym rozkładzie danych (w tym danych o rozkładzie skośnym).
- Daje najlepsze wyniki, gdy w danych sÄ… naturalne klastry.
- Nie najlepszy wybór do porównań między latami lub zbiorami danych.
- Dla każdego roku otrzymamy optymalne rozwiązanie, zakresy nie będą porównywalne.
In [15]:
counties_attr.plot(column = "WHITE",
cmap = "YlOrBr",
k = 5,
scheme= "natural_breaks",
legend=True)
Out[15]:
<Axes: >
In [16]:
#lokalizacja legendy
counties_attr.plot(column = "WHITE",
cmap = "YlOrBr",
k = 5,
scheme= "natural_breaks",
legend=True,
legend_kwds={"loc": "center left", "bbox_to_anchor": (1, 0.5)}
)
Out[16]:
<Axes: >
Kompozycja mapy¶
In [17]:
from matplotlib_scalebar.scalebar import ScaleBar
fig, ax = plt.subplots(1, figsize=(10, 6))
norm = mpl.colors.Normalize(vmin=0, vmax=1)
counties_attr.plot(column = "BLACK",
cmap = "YlOrBr",
norm = norm,
linewidth = 0.5,
ax = ax,
legend = True,
legend_kwds={"location": "bottom","label": "Percent of Blacks", "orientation": "horizontal", 'shrink': 0.3})
ax.set_axis_off()
#add title
ax.set_title('Distribution of Blacks', fontdict={'fontsize': '25', 'fontweight' : '3'})
#create annotation for data source
ax.annotate('Source: ACS 2012-2016',xy=(0.1, .08), xycoords='figure fraction', horizontalalignment='left', verticalalignment='top', fontsize=12, color='#555555')
#add scale bar
ax.add_artist(ScaleBar(dx=1, location="lower right", dimension="si-length", units="km"))
#add colorbar
#sm = plt.cm.ScalarMappable(cmap='YlOrBr', norm=norm)
# empty array for the data range
#sm._A = []
# add the colorbar to the figure
#cbar = fig.colorbar(sm)
#saving our map as .png file.
fig.savefig('map_export.png', dpi=300)