19. Python – Wykresy (Matplotlib i Seaborn)


Wprowadzenie

Wizualizacja danych to kluczowy element analizy – pozwala szybko zrozumieć dane i wyciągnąć wnioski.

Biblioteki:

  • Matplotlib – podstawowa, najpopularniejsza
  • Seaborn – ładniejsze wykresy, bazuje na Matplotlib
  • Plotly – interaktywne wykresy

Matplotlib – podstawy

Instalacja

pip install matplotlib

Pierwszy wykres – linia

import matplotlib.pyplot as plt

# Dane
x = [1, 2, 3, 4, 5]
y = [2, 4, 6, 8, 10]

# Stwórz wykres
plt.plot(x, y)

# Opisy
plt.title('Mój pierwszy wykres')
plt.xlabel('Oś X')
plt.ylabel('Oś Y')

# Pokaż
plt.show()

Personalizacja linii

import matplotlib.pyplot as plt

x = [1, 2, 3, 4, 5]
y = [2, 4, 6, 8, 10]

# Styl linii
plt.plot(x, y, 
         color='red',          # Kolor
         linewidth=2,          # Grubość
         linestyle='--',       # Styl: '-', '--', '-.', ':'
         marker='o',           # Markery: 'o', 's', '^', '*'
         markersize=8,         # Rozmiar markerów
         label='Dane 1')       # Etykieta

plt.title('Wykres z personalizacją')
plt.xlabel('X')
plt.ylabel('Y')
plt.legend()  # Pokaż legendę
plt.grid(True)  # Siatka
plt.show()

Wiele linii na jednym wykresie

import matplotlib.pyplot as plt

x = [1, 2, 3, 4, 5]
y1 = [2, 4, 6, 8, 10]
y2 = [1, 3, 5, 7, 9]
y3 = [3, 5, 4, 6, 8]

plt.plot(x, y1, label='Linia 1', marker='o')
plt.plot(x, y2, label='Linia 2', marker='s')
plt.plot(x, y3, label='Linia 3', marker='^')

plt.title('Wiele linii')
plt.xlabel('X')
plt.ylabel('Y')
plt.legend()
plt.grid(True)
plt.show()

Typy wykresów

Wykres punktowy (scatter)

import matplotlib.pyplot as plt

x = [1, 2, 3, 4, 5, 6]
y = [2, 4, 5, 7, 8, 10]

plt.scatter(x, y, 
            s=100,           # Rozmiar punktów
            c='red',         # Kolor
            alpha=0.6,       # Przezroczystość
            edgecolors='black')  # Obramowanie

plt.title('Wykres punktowy')
plt.xlabel('X')
plt.ylabel('Y')
plt.show()

Wykres słupkowy (bar)

import matplotlib.pyplot as plt

kategorie = ['A', 'B', 'C', 'D', 'E']
wartosci = [23, 45, 56, 78, 32]

plt.bar(kategorie, wartosci, 
        color='skyblue',
        edgecolor='black',
        width=0.6)

plt.title('Wykres słupkowy')
plt.xlabel('Kategoria')
plt.ylabel('Wartość')
plt.show()

Wykres słupkowy poziomy

import matplotlib.pyplot as plt

kategorie = ['Produkt A', 'Produkt B', 'Produkt C']
wartosci = [150, 230, 180]

plt.barh(kategorie, wartosci, color='lightgreen')
plt.title('Sprzedaż produktów')
plt.xlabel('Liczba sprzedanych')
plt.show()

Histogram

import matplotlib.pyplot as plt
import numpy as np

# Dane - rozkład normalny
dane = np.random.randn(1000)

plt.hist(dane, 
         bins=30,           # Liczba słupków
         color='purple',
         alpha=0.7,
         edgecolor='black')

plt.title('Histogram')
plt.xlabel('Wartość')
plt.ylabel('Częstość')
plt.show()

Wykres kołowy (pie)

import matplotlib.pyplot as plt

kategorie = ['Python', 'Java', 'JavaScript', 'C++']
udzialy = [40, 25, 20, 15]

plt.pie(udzialy, 
        labels=kategorie,
        autopct='%1.1f%%',  # Pokaż procenty
        startangle=90,       # Kąt początkowy
        colors=['#ff9999', '#66b3ff', '#99ff99', '#ffcc99'])

plt.title('Popularne języki programowania')
plt.show()

Wyciągnięty kawałek (explode)

import matplotlib.pyplot as plt

kategorie = ['Python', 'Java', 'JavaScript', 'C++']
udzialy = [40, 25, 20, 15]
explode = [0.1, 0, 0, 0]  # Wyciągnij pierwszy

plt.pie(udzialy, 
        labels=kategorie,
        autopct='%1.1f%%',
        explode=explode,
        shadow=True)

plt.title('Języki programowania')
plt.show()

Wykres pudełkowy (box plot)

import matplotlib.pyplot as plt
import numpy as np

# Dane dla różnych grup
dane1 = np.random.normal(100, 10, 200)
dane2 = np.random.normal(90, 20, 200)
dane3 = np.random.normal(80, 5, 200)

dane = [dane1, dane2, dane3]

plt.boxplot(dane, labels=['Grupa A', 'Grupa B', 'Grupa C'])
plt.title('Box Plot')
plt.ylabel('Wartości')
plt.show()

Wiele wykresów (subplots)

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 10, 100)

# Stwórz siatkę 2x2
fig, axes = plt.subplots(2, 2, figsize=(10, 8))

# Wykres 1
axes[0, 0].plot(x, np.sin(x))
axes[0, 0].set_title('sin(x)')

# Wykres 2
axes[0, 1].plot(x, np.cos(x), 'r')
axes[0, 1].set_title('cos(x)')

# Wykres 3
axes[1, 0].plot(x, x**2, 'g')
axes[1, 0].set_title('x²')

# Wykres 4
axes[1, 1].plot(x, np.exp(x/10), 'purple')
axes[1, 1].set_title('e^(x/10)')

plt.tight_layout()  # Automatyczne dopasowanie
plt.show()

Zapisywanie wykresów

import matplotlib.pyplot as plt

x = [1, 2, 3, 4, 5]
y = [2, 4, 6, 8, 10]

plt.plot(x, y)
plt.title('Mój wykres')

# Zapisz do pliku
plt.savefig('wykres.png', dpi=300, bbox_inches='tight')
# plt.savefig('wykres.pdf')  # PDF
# plt.savefig('wykres.svg')  # SVG

print("Wykres zapisany!")

Pandas + Matplotlib

Pandas ma wbudowaną integrację z Matplotlib.

import pandas as pd
import matplotlib.pyplot as plt

# DataFrame
df = pd.DataFrame({
    'Miesiąc': ['Sty', 'Lut', 'Mar', 'Kwi', 'Maj'],
    'Sprzedaż': [120, 150, 180, 160, 200]
})

# Wykres bezpośrednio z DataFrame
df.plot(x='Miesiąc', y='Sprzedaż', kind='bar', color='skyblue')
plt.title('Sprzedaż miesięczna')
plt.ylabel('Sprzedaż')
plt.show()

# Inne typy: 'line', 'bar', 'barh', 'hist', 'box', 'scatter', 'pie'

Seaborn – piękniejsze wykresy

Instalacja

pip install seaborn

Podstawy Seaborn

import seaborn as sns
import matplotlib.pyplot as plt

# Ustaw styl
sns.set_style('darkgrid')  # 'darkgrid', 'whitegrid', 'dark', 'white', 'ticks'

# Dane
tips = sns.load_dataset('tips')  # Przykładowy zbiór danych

# Wykres punktowy z linią trendu
sns.scatterplot(data=tips, x='total_bill', y='tip')
plt.title('Rachunek vs Napiwek')
plt.show()

Wykres z regresją liniową

import seaborn as sns
import matplotlib.pyplot as plt

tips = sns.load_dataset('tips')

# Scatter plot + linia trendu
sns.regplot(data=tips, x='total_bill', y='tip')
plt.title('Rachunek vs Napiwek (z trendem)')
plt.show()

Wykres skrzypcowy (violin)

import seaborn as sns
import matplotlib.pyplot as plt

tips = sns.load_dataset('tips')

sns.violinplot(data=tips, x='day', y='total_bill')
plt.title('Rachunki według dni tygodnia')
plt.show()

Heatmapa (korelacja)

import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd

# Dane
df = pd.DataFrame({
    'A': [1, 2, 3, 4, 5],
    'B': [2, 4, 6, 8, 10],
    'C': [5, 4, 3, 2, 1]
})

# Macierz korelacji
korelacja = df.corr()

# Heatmapa
sns.heatmap(korelacja, 
            annot=True,      # Pokaż wartości
            cmap='coolwarm', # Paleta kolorów
            center=0)        # Wyśrodkuj na 0

plt.title('Macierz korelacji')
plt.show()

Pair plot

import seaborn as sns
import matplotlib.pyplot as plt

# Załaduj dane
iris = sns.load_dataset('iris')

# Wykres wszystkich par zmiennych
sns.pairplot(iris, hue='species')
plt.show()

Praktyczne przykłady

Przykład 1: Analiza sprzedaży

import pandas as pd
import matplotlib.pyplot as plt

# Dane sprzedażowe
sprzedaz = pd.DataFrame({
    'Miesiąc': ['Sty', 'Lut', 'Mar', 'Kwi', 'Maj', 'Cze'],
    'Sprzedaż': [12000, 15000, 13000, 18000, 22000, 25000],
    'Cel': [15000, 15000, 15000, 20000, 20000, 20000]
})

# Wykres
plt.figure(figsize=(10, 6))
plt.plot(sprzedaz['Miesiąc'], sprzedaz['Sprzedaż'], 
         marker='o', linewidth=2, label='Rzeczywista')
plt.plot(sprzedaz['Miesiąc'], sprzedaz['Cel'], 
         marker='s', linewidth=2, linestyle='--', label='Cel')

plt.title('Sprzedaż vs Cel - 2024', fontsize=16)
plt.xlabel('Miesiąc')
plt.ylabel('Sprzedaż (PLN)')
plt.legend()
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()

Przykład 2: Porównanie produktów

import matplotlib.pyplot as plt

produkty = ['Laptop', 'Telefon', 'Tablet', 'Monitor', 'Klawiatura']
sprzedaz_q1 = [45, 78, 32, 56, 89]
sprzedaz_q2 = [52, 85, 38, 61, 95]

x = range(len(produkty))
width = 0.35

plt.figure(figsize=(10, 6))
plt.bar([i - width/2 for i in x], sprzedaz_q1, width, label='Q1', color='skyblue')
plt.bar([i + width/2 for i in x], sprzedaz_q2, width, label='Q2', color='lightgreen')

plt.title('Sprzedaż produktów - Q1 vs Q2')
plt.xlabel('Produkt')
plt.ylabel('Liczba sprzedanych')
plt.xticks(x, produkty)
plt.legend()
plt.grid(axis='y', alpha=0.3)
plt.tight_layout()
plt.show()

Przykład 3: Rozkład wieku

import matplotlib.pyplot as plt
import numpy as np

# Symulacja danych
wiek = np.random.normal(35, 10, 1000)  # Średnia 35, odchylenie 10

plt.figure(figsize=(10, 6))
plt.hist(wiek, bins=30, color='coral', edgecolor='black', alpha=0.7)
plt.axvline(wiek.mean(), color='red', linestyle='--', linewidth=2, label=f'Średnia: {wiek.mean():.1f}')

plt.title('Rozkład wieku pracowników')
plt.xlabel('Wiek')
plt.ylabel('Liczba osób')
plt.legend()
plt.grid(axis='y', alpha=0.3)
plt.show()

Przykład 4: Dashboard z wieloma wykresami

import matplotlib.pyplot as plt
import pandas as pd

# Dane
df = pd.DataFrame({
    'Miesiąc': ['Sty', 'Lut', 'Mar', 'Kwi'],
    'Przychód': [12000, 15000, 13000, 18000],
    'Koszty': [8000, 9000, 8500, 11000],
    'Klienci': [120, 145, 130, 170]
})

df['Zysk'] = df['Przychód'] - df['Koszty']

# Stwórz dashboard
fig, axes = plt.subplots(2, 2, figsize=(14, 10))
fig.suptitle('Dashboard Sprzedażowy - Q1 2024', fontsize=16)

# Wykres 1: Przychód i koszty
axes[0, 0].plot(df['Miesiąc'], df['Przychód'], marker='o', label='Przychód')
axes[0, 0].plot(df['Miesiąc'], df['Koszty'], marker='s', label='Koszty')
axes[0, 0].set_title('Przychód i Koszty')
axes[0, 0].set_ylabel('PLN')
axes[0, 0].legend()
axes[0, 0].grid(True, alpha=0.3)

# Wykres 2: Zysk
axes[0, 1].bar(df['Miesiąc'], df['Zysk'], color='green', alpha=0.7)
axes[0, 1].set_title('Zysk')
axes[0, 1].set_ylabel('PLN')
axes[0, 1].grid(axis='y', alpha=0.3)

# Wykres 3: Liczba klientów
axes[1, 0].plot(df['Miesiąc'], df['Klienci'], marker='D', color='purple', linewidth=2)
axes[1, 0].set_title('Liczba klientów')
axes[1, 0].set_ylabel('Klienci')
axes[1, 0].grid(True, alpha=0.3)

# Wykres 4: Udział przychodów
axes[1, 1].pie(df['Przychód'], labels=df['Miesiąc'], autopct='%1.1f%%', startangle=90)
axes[1, 1].set_title('Udział przychodów')

plt.tight_layout()
plt.show()

Podsumowanie

Matplotlib:

  • plt.plot() – wykres liniowy
  • plt.scatter() – wykres punktowy
  • plt.bar() / plt.barh() – słupkowy
  • plt.hist() – histogram
  • plt.pie() – kołowy
  • plt.boxplot() – pudełkowy
  • plt.subplots() – wiele wykresów

Personalizacja:

  • colorlinewidthlinestylemarker
  • title()xlabel()ylabel()
  • legend()grid()
  • savefig() – zapis do pliku

Seaborn:

  • Ładniejsze style
  • scatterplot()regplot()violinplot()
  • heatmap() – korelacja
  • pairplot() – wszystkie pary

Integracja z Pandas:

  • df.plot() – bezpośrednie wykresy z DataFrame