In [1]:
import warnings
warnings.filterwarnings('ignore')
In [2]:
import os
import sqlite3
import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
import pickle

Seaborn/Matplotlib - grafika prezentacyjna

Wizualizacja danych geoprzestrzenych w Pythonie obejmuje co najmniej dwa zagadnienia:

  • Wizualizację informacji nieprzestrzennej - w postaci diagramów, wykresów itp
  • wizualizację struktury przestrzennej (w postaci map lub serii map)

Informacja nieprzestrzenna przechowywana jest - tak jak w innych systemach obliczeniowych w formie serii danych (jednego typu) lub zestawu serii jednakowych długości (ramki danych - dataFrame). Przechowywanie, zarządzanie i import danych zostało omówione w poprzedniej części dotyczącej biblioteki pandas, w tej części zajmiemy się narzędziem dedykowanym wizualizacji danych nieprzestrzennych - seaborn. Jest to biblioteka zbudowana na podstawie matplotlib i w założeniu umożliwia szybkie tworzenie zaawansowanych wykresów o dużej swobodzie modyfikacji. Wykresy seaborn są wykresami matplotlib w związku z tym w przypadku braku określonej funkcjonalności w pakiecie seaborn może być uzupełniona funkcjami matplotlib, umożliwiając tworzenie bardzo zaawansowanych grafik.

Alternatywy

Podstawą pracy pakietu seaborn jest biblioteka pandas. Wiele funkcji seaborn wymaga danych przechowywanych w postaci pandas.DataFrame i wymaga jawnego skonwertowania innych typów danych -- głównie numpy.array do formatu pandas. Ponieważ dane przeznaczone do wizualizacji często wymagają wcześniejszej zaawansowanej obróbki (wczytania danych, zamiany, konwersji typów itp) warto takie dane zapisać bezpośrednio w formacie pandas. Służy do tego poznany już uniwersalny format zapisu danych pickle, który zachowuje strukturę wewnętrzną danych.

Do załadowania gotowych do użycia danych (przygotowanych w poprzedniej części służy polecenie picke.load() wymagające jako źródła otwarcia wcześniej zapisanego pliku

In [3]:
os.chdir('/home/jarekj/Dropbox/dydaktyka/programowanie4/powiatData')
dt = pickle.load(open("dt.p","rb+"))
dt.head()
Out[3]:
ogc_fid fid powiat m k aprod prod pprod malzenstwa przyrost woj
0 1 1 złotoryjski 22059 22997 6451 31248 7357 4.6 -2.3 DOLNOŚLĄSKIE
1 2 2 Legnica 48273 53719 13691 68317 19984 4.4 -2.3 DOLNOŚLĄSKIE
2 3 3 jeleniogórski 31460 33711 8696 44540 11935 3.9 -4.4 DOLNOŚLĄSKIE
3 4 4 górowski 17989 18402 5855 24457 6079 5.3 -0.7 DOLNOŚLĄSKIE
4 5 5 oleśnicki 51929 54159 16488 71646 17954 4.7 0.3 DOLNOŚLĄSKIE

Prezentacja danych kategoryzowanych

Dane kategoryzowane, to takie, które gdzie dla każdego rekordu (wiersza) wartość zmiennej jest określona przynależnością do pewnej (nieunikalnej) kategorii. W naszym zbiorze danych taką funkcję pełni zmienna "woj(ewództwo)", która wskazuje na terenie jakiego województwa leży dany powiat. Pojedyncza zmienna kategoryzowana może być przedstawiona wyłącznie w postaci liczności/udziału danej kategorii względem całej zmiennej. Do prezentacji takiej zmiennej służy wykres countplot(), który wyświetla w postaci słupka ilość wystąpień danej kategorii w zmiennej.

Note: ogólne typy wykresów

Od wersji 0.9 seaborn wprowadził uogólnione typy wykresów: catplot i relplot. Wykresy domyślnie używają najlepszej opcji dla typu danych lub wymagają podania typu wykresu jawnie. Na przykład: catplot(..., kind="count") jest równoważne: countplot(...). Wykresy ogólne, mimo że wygodne mają swoje ograniczenia które zostaną wskazane w dalszych częściach kursu.

In [4]:
sns.countplot(x="woj",data=dt)
Out[4]:
<matplotlib.axes._subplots.AxesSubplot at 0x7fe862684550>

Note: rotacja wykresu i etykiet.

Jednym z największych problemów grafiki prezentacyjnej jest to że etykiety często nie mieszczą się w obszarze przeznaczonym dla etykiety przez twórcę programu. W takiej sytuacji możemy:

  • dostosować układ wykresu do etykiet, poprzez zmianę jego orientacji
  • dostosować rozmiar etykiety do możliwości wykresu, poprzez ich skrócenie lub zastąpienie skrótami
  • dokonać rotacji etykiet

Seaborn pozwala na wybór orientacji wykresu. Jeżeli spodziewamy się że etykiety są za długie i będą się nakładały można obrócić wykres do orientacji poziomej. Należy wtedy dodatkowo zmienić funkcję osi x z y. Niestety nie ma możliwości sterowania szerokością i odległoscią słupków.

In [5]:
sns.countplot(y="woj",data=dt,orient="h")
Out[5]:
<matplotlib.axes._subplots.AxesSubplot at 0x7fe8605cac88>

Jeżeli zależy nam na układzie pionowym można skrócić lub obrócić etykiety. Aby skrócić etykietę do określonej liczny znaków należy zastosować metodę polegającą na potraktowaniu napisu jako krotki i wybraniu z niego określonego fragmentu poprzez indeksowanie: napis[:10] zwróci nam pierwsze 10 znaków. Można więc zastosować metodę dla każdego rekordu w dataFrame poprzez metodę df.apply. Metoda apply wymaga podania funkcji, która zostanie zastosowana, ponieważ takiej funkcji nie ma trzeba ją stworzyć tymczasowo poprzez poznany wcześniej operator lambda umożliwiający tworzenie funkcji anonimowych. lambda x: x[:10] utworzy funkcję zwracającą 10 pierwszych elementów listy/krotki/tektu.

Do obrócenia etykiet służy funkcja matplotlib definiująca właściwości etykiet (ticks), gdzie ustawiamy dla etykiet x rotację na 90 stopni.

In [6]:
dtl = dt.assign(wojewodztwo=dt.woj.apply(lambda x: x[:10]))
sns.countplot(x="wojewodztwo",data=dtl)
plt.xticks(rotation=90)
Out[6]:
(array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15]),
 <a list of 16 Text xticklabel objects>)

Wykresy przedstawiające rozkład zmiennej numerycznej

Zmienna numeryczna to taka zmienna, która przybiera dowolne wartości albo z całej dziedziny liczb rzeczywistych albo z ich pewnego przedziału. Do prezentacji tych zmiennych służą wykresy prezentujące rozkład distplot() najczęściej w postaci histogramu, lub rozkład w postaci ciągłej: kdeplot() (kernel density estimation). Do opisu gęstości można też użyć wykresu kreskowego rugplot(), który najczęściej jest łączony z innymi wykresami. Jako przykład przedstawimy standardowy wykres rozkładu z pocją rug, który łączy w jednym wykresie histogram, odpowiadający mu wykres kde oraz rugplot ilustrujący gęstość poszczególnych wystąpień:

In [7]:
sns.distplot(dt['przyrost'],rug=True)
Out[7]:
<matplotlib.axes._subplots.AxesSubplot at 0x7fe8605b3e48>

Wyresy gęstościowe kde mają kilka dodatkowych parametów pozwalających sterować wyglądem krzywej gęstości: typ kernela i szerokość pasma wygładzania (bandwith - bw)

In [8]:
import statsmodels
sns.kdeplot(dt['przyrost'],bw=0.2, kernel='tri') #kerenl density with bandwith and triangle kernel
Out[8]:
<matplotlib.axes._subplots.AxesSubplot at 0x7fe860491b70>

Wykresy rozkładu można modyfikować ilością skalą przedziałów, można też dopasować do wybranych rozkładów. Tu użyjemy rozkładu normalnego. Rozkład trzeba wcześniej zaimportować z biblioteki scpipy

In [9]:
from scipy.stats import norm
sns.distplot(dt['przyrost'],bins=20, fit=norm,kde=False) # z dopasowaniem do rozkładu normalnego
Out[9]:
<matplotlib.axes._subplots.AxesSubplot at 0x7fe860491d68>

Wizualizacja zmiennych złożonych/kompozytowych (composite)

Zmienne złożone to takie zmienne, których udział sumuje się do jedności (właściwa definicja to taka, że przynajmniej jeden ze składników jest negatywnie skorelowany z pozostałymi). Przyjmując definicję uproszczoną najprostrzą formą wykresu dla zmiennej złożonej jest wykres stertowy (stacked bar plot), niestety z powodów zrozumiałych wyłącznie dla siebie twórcy pakietu odmawiają wprowadzenia tego wykresu do biblioteki seaborn. Z tego powodu przygotowanie tego wykresu będzie nieco bardziej skomplikowane i będzie wymagało przeliczenia danych w obrębie dataFrame oraz wykorzystanie właściwości seaborn, pozwalające nakładać na siebie kolejne warstwy wykresu. W ten sposób omówimy wybrane mechanizmy związane z tworzeniem złożonych wykresów, których nie ma w bazie szablonów.

Do zilustrowania zadania użyjemy fragment dataFrame zawierający dane na temat ilości osób w wieku przedprodukcyjnym, (aprod) produkcyjnym i poprodukcyjnym (pprod)

Modelowanie danych. W na tym etapie musimy:

  1. Pogrupować dataFrame wg kolumny woj, tak aby kolumny pprod, prod i aprod zawierały sumy osób dla poszczegolnych województw
  2. Dodać kolumnę przechowującą sumę mieszkańców dla każdego województwa:
  3. Ponieważ wykres jest stertą danych każdy słupek powyżej zawiera w sobie część słupka poniżej a więc musimy dodać trzy kolumny: zawierające względny udział mieszkańców danej grupy i grupy poprzedniej: (A) przedprodukcyjne pprod/sum * 100, (B) produkcyjne (pprod+prod)/sum i dla poprodukcyjnej (C) 100 bo jest to jednocześnie suma wszystkich mieszkańców (100%).
In [10]:
dtg = dt[["aprod","prod","pprod","woj"]].groupby("woj").sum()
dtg['sum'] = dtg['aprod']+dtg['prod']+dtg['pprod']
dtg['saprod'] = dtg['aprod']/dtg['sum']*100
dtg['sprod'] = (dtg['aprod']+dtg['prod'])/dtg['sum']*100
dtg['spprod'] = 100

Tworzenie wykresu Na tym etapie:

  1. tworzymy wykres o orientacji horyzontalnej najpierw dla grupy popordukcyjnej o wysokości 100%
  2. Na to nakładamy wykres dla środkowy dla grupy produkcyjnej
  3. Na końcu dodajemy najniższą część dla grupy przedprodukcyjnej
  4. Na końcu modyfikujemy etykietę osi x na "grupy wiekowe"

Wykres jest gotowy. Niestety jak poprzednio nie możemy modyfikować szerokości słupków.

In [11]:
sns.barplot(y=dtg.index, x="spprod",data=dtg,ci=None,color="red",orient="h")
sns.barplot(y=dtg.index, x="sprod",data=dtg,ci=None,color="yellow",orient="h")
bar=sns.barplot(y=dtg.index, x="saprod",data=dtg,ci=None,color="green",orient="h")
bar.set_xlabel("grupy wiekowe")
Out[11]:
Text(0.5,0,'grupy wiekowe')

Porównanie dwóch i więcej zmiennych

Najprostrzym porównaniem jest wykres porównujący rozproszenie wartości dla pary zmiennych, gdzie wartości każdej ze zmiennych przedstawiane są na odpowiednich osiach. Dodatkowo do poszczególnych zmiennych można dodać atrybut przedstawiający kolejną zmienną, zarówno numeryczną jak i kategoryzowaną. Wykresy tego typu, określane są jako scatterplot(), seaborn używa dla nich nazwy relplot().

Jako przykład przedstawimy porównanie dwóch zmiennych: ilości małżeństw i przyrostu naturalnego:

In [12]:
sns.relplot(x="malzenstwa",y="przyrost",data=dt)
Out[12]:
<seaborn.axisgrid.FacetGrid at 0x7fe8f83aa390>

Dodatkowo, aby wykryć czy zróżnicowanie posiada strukturę przestrzenną do zróżnicowania obiektów użyjemy informacji na temat województwa. Kolor jest definiowany parametrem hue.

In [13]:
sns.relplot(x="malzenstwa",y="przyrost",hue="woj",data=dt) 
Out[13]:
<seaborn.axisgrid.FacetGrid at 0x7fe860491eb8>

Kolor może też przedstawiać zmienną numeryczną. Użyjemy tu wskaźnika feminizacji: czyli proporcji między kobietami i mężczyznami, który jednak trzeba wyliczyć w locie i dodać do dataFrame. Dodatkowo, dodamy parametr alpha, który nada przeźroczystość wyświetlanym punktom lepiej ilustrując rzeczywistą informację o relacji osób w wieku przed i poprodukcyjnym i wskaźnika feminizacji. Dodatkowo w celu wyeliminowania Warszawy zmniejszymy zasięg obu osi, tak aby wyeksponować zróżnicowanie w pozostałych powiatach.

In [14]:
sns.relplot(x="pprod",y="aprod",hue="fem",data=dt.assign(fem=dt.k/dt.m),alpha=0.5)
plt.ylim(0, 100000)
plt.xlim(0, 100000)
Out[14]:
(0, 100000)

Wykresy pozwalające porównać wzajemnie wszystkie zmienne są jednym z najważniejszych narzędzi eksploracji danych. Pozawalają wizualnie wykryć zmienne skorelowane, skupienia w danych, czy inne subtelne zależności. Wykresy te określane jako porównawcze (pairplot) składają się z macierzy par wszystkich zmiennych oraz na przekątnej jednego z wykresów ilustrujących rozkład w obrębie danej zmiennej.

In [15]:
sns.pairplot(data=dt[["prod","malzenstwa","przyrost"]])
#sns.pairplot(data=dt,vars=["aprod","prod","pprod"])
Out[15]:
<seaborn.axisgrid.PairGrid at 0x7fe8f82a7da0>

Zarówno wykresy jak i przekątna mogą zostać zmodyfikowane. Jako przykład zmienimy przekątną z histogramu na wykres gęstościowy oraz zróżnicujemy kolorystycznie województwa (dwa wybrane: pomorskie i lubelskie). Dodatkowo zmodyfikujemy wielkość punktu i jego przeźroczystość. Ponieważ zarówno część macierzowa jak i przekątna to osobne typy wykresów do ich modyfikacji potrzebujemy osobne zestawy argumentów: przekazywanych jako słowniki plot_kws i diag_kws

In [16]:
dtm = dt.loc[dt.woj.isin(['POMORSKIE','LUBELSKIE']),["aprod","prod","pprod","woj"]]
sns.pairplot(data=dtm,hue="woj",plot_kws=dict(s=100, alpha=0.3),diag_kind="kde")
Out[16]:
<seaborn.axisgrid.PairGrid at 0x7fe89b311dd8>

Zróżnicowanie zmiennej w obrębie kategorii

Liczna seria wykresów ma na celu zilustrowanie rozkładu zmiennej w obrębie kategorii. O ile rozkład zmiennej lepiej ilustrować wykresami rozkładu (kde, dist) o tyle porównanie rozkładu tej samej zmiennej ale w obrębie kategorii lepiej ilustrować przy pomocy wykresów pudełkowych lub ich odmian: wykresu skrzypcowego (violin) albo pasmowego (strip). Jako ilustrację dla tych wykresów użyjemy porównania rozkładu wskaźnika małżeństw dla czterech województw, dodatkowo omówimy definiowanie własnej palety kolorów dla zmiennej kategoryzowanej. Paletę kolorów definiujemy jako słownik, gdzie kategoria jest kluczem, a kolor (zapisany w formacie #KKKKKK) jest wartością słownika. Co ciekawe definiując klucze słownika możemy od razu ich użyć do redukcji wielkości dataFrame przy pomocy poznanej już wcześniej metody DataFrame.isin()

In [17]:
ww = ['POMORSKIE','LUBELSKIE','LUBUSKIE','WIELKOPOLSKIE']
colors = ['#4FC3FF','#FFF03D','#008004','#A5811F']
pal = dict(zip(ww,colors))
dtm = dt.loc[dt.woj.isin(ww),["malzenstwa","woj"]]

sns.catplot(x="woj",y="malzenstwa",data=dtm,kind="box",palette=pal)
plt.xticks(rotation=90)
Out[17]:
(array([0, 1, 2, 3]), <a list of 4 Text xticklabel objects>)

Zróżnicowanie zmiennej w obrębie kategorii

Liczna seria wykresów ma na celu zilustrowanie rozkładu zmiennej w obrębie kategorii. O ile rozkład zmiennej lepiej ilustrować wykresami rozkładu (kde, dist) o tyle porównanie rozkładu tej samej zmiennej ale w obrębie kategorii lepiej ilustrować przy pomocy wykresów pudełkowych lub ich odmian: wykresu skrzypcowego (violin) albo pasmowego (strip). Jako ilustrację dla tych wykresów użyjemy porównania rozkładu wskaźnika małżeństw dla czterech województw, dodatkowo omówimy definiowanie własnej palety kolorów dla zmiennej kategoryzowanej. Paletę kolorów definiujemy jako słownik, gdzie kategoria jest kluczem, a kolor (zapisany w formacie #KKKKKK) jest wartością słownika. Co ciekawe definiując klucze słownika możemy od razu ich użyć do redukcji wielkości dataFrame przy pomocy poznanej już wcześniej metody DataFrame.isin()

Słabą stroną wykresu pudełkowego jest to że nie widzimy szczegółowego rozkładu wartości w obrębie kategorii a jedynie estymatory rozkładu. Alternatywą jest wykres pasmowy, który umieszcza rozproszone (jitter) punkty w miejscu rzeczywistego występowania wartości. Aby jednocześnie porównać go z wykresem pudełkowym, użyjemy metody subplot() z biblioteki matplotlib, która pozwala na umieszczanie obok siebie niezależnych wykresów.

Note: Terminologia matplotlib: fig (rycina) i axes (wykres)

Terminologia stosowana w w matplotlib może być myląca ze względu na dwa pojęcia: figure i axes. Figure (fig) określa nam cały rysunek, który może składać się z wykresów. Każdy z wykresów określany jest jako axes (osie) gdyż jest wyznaczany niezależnym układem współrzędnych. Różne funkcje mogą się odnosić do różnych elementów figury lub wykresów. W dalszej części będziemy stosować polskie terminu figura na obiekt nadrzędny (fig, plot) i wykres (axes) na elementy składowe figury.

In [18]:
fig, (ax1, ax2) = plt.subplots(1,2,figsize=(8,4))
sns.stripplot(x="woj",y="malzenstwa",data=dtm,palette=pal,ax=ax1)
_ = plt.setp(ax1.get_xticklabels(), rotation=90)
sns.boxplot(x="woj",y="malzenstwa",data=dtm,palette=pal,ax=ax2)
_ = plt.setp(ax2.get_xticklabels(), rotation=90)

Możemy też porównać kategorie w taki sposób, że każda z nich zostanie przestawiona w postaci osobnego wykresu rozkładu. Można do tego użyć wykresu typau FacetGrid, który tworzy osobne wykresy (axes) dla każdej kategorii a następnie wypełnia go odpowiednią częścią danych ze wskazanej zmiennej (małżeństwa) w zależności od wskazanej wcześniej zmiennej grupującej (woj).

In [19]:
g = sns.FacetGrid(dtm, col="woj", col_wrap=2)
g = g.map(sns.distplot, "malzenstwa")

Zależność między zmiennymi

Jeżeli zależy nam na przedstawieniu relacji pomiędzy dwiema zmiennymi kategoryzowanymi możemy użyć dodatkowej kategoryzowanej zmiennej grupującej, którą przypiszemy do jednej z właściwości wykresu: hue/color. Jeżeli nasza zmienna występuje w postaci pojedynczych wsystąpień musimy użyć countplot, jeżeli natomiast w postaci podsumowań: barplot. Jako przykład przedstawimy zróżnicowanie pomiędzy województwami w ilości kobiet i mężczyzn. W tym celu musimy w pierwszej kolejności zamienić format danych z szerokiego (każda kolumna to osobna cecha/zmienna) na wąski, gdzie jedna kolumna zawiera nazwy zmiennych a druga odpowidnie wartości. Dodatkowe kolumny mogą przechowywać zmienne grupujące. Do takiej operacji służy metoda df.melt(), która dokonuje konwersji z układu szerokiego na wąski (w przeciwnymi kierunku używamy df.cast()). Metoda wymaga wskazania zmiennych grupujących (tu "woj") oraz nazw kolumn przechowujących nazwy zmiennych _var_name_ tu: "plec" i value\ name: tu: "licznosc". Następnie wykonujemy wykres wskazując "woj" jako zmienną x, liczność jako y i płeć jako zmienną grupującą przy pomocy barwy (hue).

In [20]:
dtm = pd.melt(dt[["k","m","woj"]],"woj",var_name="plec", value_name="licznosc")
sns.barplot(x="woj",y="licznosc",hue="plec", data=dtm,ci=None)
plt.xticks(rotation=90)
dtm
Out[20]:
woj plec licznosc
0 DOLNOŚLĄSKIE k 22997
1 DOLNOŚLĄSKIE k 53719
2 DOLNOŚLĄSKIE k 33711
3 DOLNOŚLĄSKIE k 18402
4 DOLNOŚLĄSKIE k 54159
5 DOLNOŚLĄSKIE k 46344
6 DOLNOŚLĄSKIE k 43750
7 DOLNOŚLĄSKIE k 85215
8 DOLNOŚLĄSKIE k 28830
9 DOLNOŚLĄSKIE k 29979
10 DOLNOŚLĄSKIE k 54808
11 DOLNOŚLĄSKIE k 42306
12 DOLNOŚLĄSKIE k 46323
13 DOLNOŚLĄSKIE k 62284
14 DOLNOŚLĄSKIE k 24301
15 DOLNOŚLĄSKIE k 47761
16 DOLNOŚLĄSKIE k 65157
17 DOLNOŚLĄSKIE k 34866
18 DOLNOŚLĄSKIE k 38728
19 DOLNOŚLĄSKIE k 31929
20 DOLNOŚLĄSKIE k 26555
21 DOLNOŚLĄSKIE k 26516
22 DOLNOŚLĄSKIE k 18839
23 DOLNOŚLĄSKIE k 23022
24 DOLNOŚLĄSKIE k 22420
25 DOLNOŚLĄSKIE k 83255
26 DOLNOŚLĄSKIE k 28015
27 DOLNOŚLĄSKIE k 337405
28 DOLNOŚLĄSKIE k 54703
29 DOLNOŚLĄSKIE k 24208
... ... ... ...
730 WIELKOPOLSKIE m 40560
731 WIELKOPOLSKIE m 27975
732 WIELKOPOLSKIE m 29908
733 WIELKOPOLSKIE m 48376
734 WIELKOPOLSKIE m 36698
735 WIELKOPOLSKIE m 23432
736 WIELKOPOLSKIE m 37699
737 WIELKOPOLSKIE m 27441
738 WIELKOPOLSKIE m 30877
739 ZACHODNIOPOMORSKIE m 41655
740 ZACHODNIOPOMORSKIE m 36697
741 ZACHODNIOPOMORSKIE m 38298
742 ZACHODNIOPOMORSKIE m 51619
743 ZACHODNIOPOMORSKIE m 194002
744 ZACHODNIOPOMORSKIE m 26625
745 ZACHODNIOPOMORSKIE m 18846
746 ZACHODNIOPOMORSKIE m 20003
747 ZACHODNIOPOMORSKIE m 20287
748 ZACHODNIOPOMORSKIE m 28503
749 ZACHODNIOPOMORSKIE m 38559
750 ZACHODNIOPOMORSKIE m 23988
751 ZACHODNIOPOMORSKIE m 59235
752 ZACHODNIOPOMORSKIE m 32952
753 ZACHODNIOPOMORSKIE m 24020
754 ZACHODNIOPOMORSKIE m 24913
755 ZACHODNIOPOMORSKIE m 40603
756 ZACHODNIOPOMORSKIE m 28642
757 ZACHODNIOPOMORSKIE m 30510
758 ZACHODNIOPOMORSKIE m 23583
759 ZACHODNIOPOMORSKIE m 33413

760 rows × 3 columns

Regresja liniowa jest najprostszą formą określenia zależności pomiędzy dwoma zmiennymi numerycznymi. Do wizualizacji regresji (liniowej i wyższych stopni) w pakiecie seaborn służy funkcja regplot(). Funkcja tworzy zwykły wykres punktowy dla którego wylicza równanie regresji i wizualizuje go w postaci linii wraz z pasmem niepewności.

In [21]:
sns.regplot("aprod","pprod",data=dt)
Out[21]:
<matplotlib.axes._subplots.AxesSubplot at 0x7fe89b055588>

Funkcja może wyliczyć modele regresji dla każdej kategorii z osobna. Ciekawą opcją jest również wyliczanie równania regresji z pominięciem wartości odstających (wymaga zainstalowania) biblioteki statsmodels i ustawienia parametru robust na True

In [22]:
#Z rozbiciem na województwa
sns.lmplot("aprod","pprod",hue="woj",data=dt.loc[dt.woj.isin(["POMORSKIE","LUBELSKIE"])])
Out[22]:
<seaborn.axisgrid.FacetGrid at 0x7fe89ae0e0b8>

Wykresy regresji można również przedstawić dla każdej kategorii osobno, wskazując zmienną dla paramteru col (od kollumny nie od koloru):

In [23]:
sns.lmplot(x='aprod', y='pprod', data=dt, col="woj", col_wrap=4, hue="woj")
Out[23]:
<seaborn.axisgrid.FacetGrid at 0x7fe89ae17978>

Do porównania dwóch (lub więcej) zmiennych można użyć dwuwymiarowych wykresów kde (kernel density estimation), które doskonale zastępują chmury punktów w wizualizacji danych wielowymiarowych.

In [24]:
sns.kdeplot(dt['malzenstwa'],dt['przyrost'],n_levels=15,cbar=True,shade=True,shade_lowest=False)
Out[24]:
<matplotlib.axes._subplots.AxesSubplot at 0x7fe89a1f40b8>

Możliwe jest również umieszczenie na jedynym wykresie kilku chmur (w celu zbadania relacji między dwoma grupami) wymaga to jednak zastosowania techniki podobnej do tworzenia wykresów stertowych tj dodawania każdego komponentu z osobna. Dwuwymiarowe wykresy KDE wymagają w pierwszym kroku przygotowania selekcji z dataFrame zawierające tylko te rekordy, które będą należały do nakładanej chmury, gdyż kde wymaga wskazania jednowymiarowego zbioru danych.

In [25]:
pom = dt.loc[dt.woj=='POMORSKIE',["malzenstwa","przyrost"]]
lub = dt.loc[dt.woj=='LUBELSKIE',["malzenstwa","przyrost"]]

ax = sns.kdeplot(pom.malzenstwa,pom.przyrost,cmap='Blues')
ax = sns.kdeplot(lub.malzenstwa,lub.przyrost,cmap='Greens')
In [26]:
import os
import numpy as np
from osgeo import gdal
from osgeo import osr