# Python w analityce danych: Matplotlib, Seaborn i wizualizacja na rozmowach kwalifikacyjnych > Praktyczny przewodnik po wizualizacji danych w Pythonie z Matplotlib i Seaborn. Wykresy, stylizacja, subploty i najczęstsze pytania z rozmów kwalifikacyjnych na stanowiska analityczne w 2026 roku. - Published: 2026-04-22 - Updated: 2026-04-22 - Author: SharpSkill - Tags: python, matplotlib, seaborn, data-visualization, data-analytics, interview - Reading time: 9 min --- Wizualizacja danych w Pythonie to jedna z najczęściej weryfikowanych umiejętności na rozmowach kwalifikacyjnych w obszarze analityki danych. Rekruterzy oczekują od kandydatów zdolności do tworzenia czytelnych wykresów z surowych danych oraz umiejętności uzasadnienia wyborów projektowych pod presją czasu. Niniejszy poradnik obejmuje Matplotlib 3.10 i Seaborn 0.13 — dwie biblioteki dominujące w technicznych rundach rekrutacyjnych na stanowiska analityków danych i data scientistów. Każdy przykład kodu działa bezpośrednio w Python 3.12+. > **Wskazówka rekrutacyjna** > > Większość rozmów kwalifikacyjnych z analityki danych zawiera rundę kodowania na żywo, w której kandydat musi wygenerować wizualizację z zestawu danych w mniej niż 15 minut. Poniższe wzorce mapują się bezpośrednio na takie ćwiczenia. ## Konfiguracja środowiska do wizualizacji danych w Pythonie Przed napisaniem jakiegokolwiek kodu wizualizacyjnego środowisko wymaga odpowiednich zależności. Czyste środowisko wirtualne pozwala uniknąć konfliktów wersji między Matplotlib, Seaborn a ich wspólnymi podstawami NumPy i Pandas. ```bash # setup.sh python -m venv venv source venv/bin/activate pip install matplotlib==3.10.8 seaborn==0.13.2 pandas numpy ``` Szybka weryfikacja potwierdza poprawność instalacji: ```python # verify_install.py import matplotlib import seaborn as sns import pandas as pd print(f"Matplotlib: {matplotlib.__version__}") print(f"Seaborn: {sns.__version__}") print(f"Pandas: {pd.__version__}") ``` Po zablokowaniu zależności kolejny krok koncentruje się na podstawach Matplotlib — fundamencie każdego wykresu Seaborn. ## Podstawy Matplotlib: Figure, Axes i API obiektowe Matplotlib oferuje dwa API: maszynę stanów pyplot i interfejs obiektowy (OO). API obiektowe zapewnia jawną kontrolę nad każdym elementem i stanowi standard oczekiwany w profesjonalnych bazach kodu oraz na rozmowach kwalifikacyjnych. ```python # bar_chart_oo.py import matplotlib.pyplot as plt import numpy as np # Przykładowe dane przychodów kwartalnych quarters = ["Q1", "Q2", "Q3", "Q4"] revenue = [42_000, 58_000, 51_000, 67_000] # Jawne tworzenie figury i osi fig, ax = plt.subplots(figsize=(8, 5)) # Rysowanie słupków z określonym kolorem ax.bar(quarters, revenue, color="#2563eb", width=0.5) # Wyraźne etykiety osi — rekruterzy to sprawdzają ax.set_xlabel("Quarter") ax.set_ylabel("Revenue (USD)") ax.set_title("Quarterly Revenue — 2025") # Formatowanie osi Y kwotami dolarowymi ax.yaxis.set_major_formatter(plt.FuncFormatter(lambda x, _: f"${x:,.0f}")) # Usunięcie górnej i prawej ramki dla czystszego wyglądu ax.spines[["top", "right"]].set_visible(False) plt.tight_layout() plt.savefig("quarterly_revenue.png", dpi=150) plt.show() ``` Kluczowe szczegóły, które zauważają rekruterzy: jawne tworzenie `fig, ax` zamiast `plt.plot()`, czytelne etykiety osi, sformatowane wartości ticków i usunięty wizualny szum (zbędne ramki). Te drobne wybory sygnalizują myślenie produkcyjne. ## Budowanie subplotów do analizy porównawczej Rozmowy kwalifikacyjne często wymagają porównywania wielu metryk obok siebie. Funkcja `subplots()` obsługuje to za pomocą układu siatkowego. ```python # subplots_comparison.py import matplotlib.pyplot as plt import numpy as np months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun"] users = [1200, 1350, 1500, 1420, 1680, 1820] revenue = [24_000, 27_000, 30_000, 28_400, 33_600, 36_400] # Dwa wykresy obok siebie ze wspólną osią X fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 5), sharey=False) # Lewy panel: wzrost użytkowników jako wykres liniowy ax1.plot(months, users, marker="o", color="#2563eb", linewidth=2) ax1.set_title("Monthly Active Users") ax1.set_ylabel("Users") ax1.spines[["top", "right"]].set_visible(False) # Prawy panel: przychody jako wykres słupkowy ax2.bar(months, revenue, color="#16a34a", width=0.5) ax2.set_title("Monthly Revenue") ax2.set_ylabel("Revenue (USD)") ax2.yaxis.set_major_formatter(plt.FuncFormatter(lambda x, _: f"${x:,.0f}")) ax2.spines[["top", "right"]].set_visible(False) fig.suptitle("Product Metrics — H1 2025", fontsize=14, fontweight="bold") plt.tight_layout() plt.savefig("product_metrics.png", dpi=150) plt.show() ``` Użycie `sharey=False` pozwala każdemu panelowi skalować się niezależnie — przychody w dolarach i użytkownicy jako liczby mają różne rzędy wielkości. `suptitle` dodaje nadrzędny tytuł nad obydwoma subplotami. > **Typowy błąd na rozmowie** > > Kandydaci często używają `plt.plot()` do wszystkiego zamiast API obiektowego. Gdy rekruter poprosi o dodanie drugiej osi Y lub korektę pojedynczego subplotu, podejście pyplot się rozpada. Zawsze warto domyślnie stosować `fig, ax = plt.subplots()`. ## Wykresy statystyczne Seaborn: od rozkładu do korelacji Seaborn bazuje na Matplotlib i specjalizuje się w wizualizacji statystycznej. Tam, gdzie Matplotlib wymaga ręcznej konfiguracji, Seaborn wnioskuje rozsądne ustawienia domyślne ze struktury danych. Analiza rozkładu — jedno z najczęstszych zadań rekrutacyjnych — wymaga jednego wywołania funkcji: ```python # distribution_analysis.py import seaborn as sns import matplotlib.pyplot as plt import pandas as pd import numpy as np # Symulacja danych o wynagrodzeniach dla dwóch działów np.random.seed(42) data = pd.DataFrame({ "salary": np.concatenate([ np.random.normal(75_000, 12_000, 200), # Engineering np.random.normal(65_000, 10_000, 150), # Marketing ]), "department": ["Engineering"] * 200 + ["Marketing"] * 150 }) # Wykres KDE porównujący rozkłady wynagrodzeń fig, ax = plt.subplots(figsize=(10, 5)) sns.kdeplot( data=data, x="salary", hue="department", # Automatyczny podział wg kategorii fill=True, # Zacieniowany obszar pod krzywą alpha=0.4, palette=["#2563eb", "#dc2626"], ax=ax # Przypisanie do jawnych osi ) ax.set_title("Salary Distribution by Department") ax.set_xlabel("Annual Salary (USD)") ax.xaxis.set_major_formatter(plt.FuncFormatter(lambda x, _: f"${x:,.0f}")) ax.spines[["top", "right"]].set_visible(False) plt.tight_layout() plt.savefig("salary_distribution.png", dpi=150) plt.show() ``` Parametr `hue` automatycznie dzieli dane, a `fill=True` uwidacznia nakładające się obszary. Ten wzorzec — grupowanie rozkładów wg kategorii — pojawia się w niemal każdym panelu rekrutacyjnym z analityki. ## Mapy ciepła Seaborn dla macierzy korelacji Mapy ciepła korelacji ujawniają zależności między zmiennymi numerycznymi na pierwszy rzut oka. Rekruterzy wykorzystują je do testowania, czy kandydaci potrafią identyfikować wielokolinearność lub zauważyć silne zależności cech. ```python # correlation_heatmap.py import seaborn as sns import matplotlib.pyplot as plt import pandas as pd import numpy as np # Symulacja metryk e-commerce np.random.seed(42) n = 500 page_views = np.random.poisson(15, n) time_on_site = page_views * 2.5 + np.random.normal(0, 5, n) cart_adds = np.random.binomial(page_views, 0.3) purchases = np.random.binomial(cart_adds, 0.4) df = pd.DataFrame({ "page_views": page_views, "time_on_site": time_on_site, "cart_adds": cart_adds, "purchases": purchases }) # Obliczenie korelacji Pearsona corr_matrix = df.corr() fig, ax = plt.subplots(figsize=(8, 6)) sns.heatmap( corr_matrix, annot=True, # Wyświetlenie wartości korelacji w komórkach fmt=".2f", # Dwa miejsca po przecinku cmap="RdBu_r", # Dywergencyjna mapa kolorów wycentrowana na 0 vmin=-1, vmax=1, # Stała skala dla spójności square=True, # Kwadratowe komórki linewidths=0.5, ax=ax ) ax.set_title("E-commerce Metrics Correlation") plt.tight_layout() plt.savefig("correlation_heatmap.png", dpi=150) plt.show() ``` Dywergencyjna mapa kolorów `RdBu_r` oznacza pozytywne korelacje na niebiesko, a negatywne na czerwono — konwencja oczekiwana przez rekruterów. Ustawienie `vmin=-1` i `vmax=1` zapewnia interpretowalność skali kolorów niezależnie od rzeczywistego zakresu danych. ## Stylizacja wykresów do profesjonalnych prezentacji Surowe wyjście Matplotlib wygląda przestarzale. Kilka linii konfiguracji przekształca wykresy w wizualizacje gotowe do prezentacji, które demonstrują dbałość o szczegóły podczas rozmów kwalifikacyjnych. ```python # professional_styling.py import matplotlib.pyplot as plt import seaborn as sns # Zastosowanie wbudowanego motywu Seaborn sns.set_theme( style="whitegrid", # Czyste tło z liniami siatki palette="muted", # Profesjonalna paleta kolorów font_scale=1.1 # Nieco większy tekst ) # Globalne nadpisania Matplotlib plt.rcParams.update({ "figure.facecolor": "white", "axes.facecolor": "white", "font.family": "sans-serif", "axes.titlesize": 14, "axes.labelsize": 12, }) ``` Zastosowanie `sns.set_theme()` na początku skryptu propaguje spójną stylizację na wszystkie kolejne wykresy. Podczas rozmów kwalifikacyjnych oszczędza to czas, który w przeciwnym razie byłby poświęcony na formatowanie poszczególnych wykresów. > **Uwaga dotycząca wersji** > > Seaborn 0.13 zdeprecjonował `set_style()` i `set_palette()` jako osobne wywołania. Zunifikowana funkcja `set_theme()` zastępuje obie. Starsze odpowiedzi ze Stack Overflow nadal odwołują się do zdeprecjonowanego API — należy ich unikać na rozmowach w 2026 roku. ## Najczęstsze pytania rekrutacyjne z wizualizacji danych Poza kodowaniem rekruterzy badają koncepcyjne rozumienie najlepszych praktyk wizualizacji. Poniższe pytania pojawiają się konsekwentnie na rozmowach z analityki danych i data science. **Kiedy należy użyć wykresu słupkowego zamiast liniowego?** Wykresy słupkowe wyświetlają porównania między dyskretnymi kategoriami (działy, typy produktów, regiony). Wykresy liniowe pokazują trendy w ciągłych lub uporządkowanych interwałach (szeregi czasowe, pomiary sekwencyjne). Użycie wykresu liniowego dla nieuporządkowanych kategorii sugeruje fałszywą relację między sąsiednimi słupkami. **Co sprawia, że wykres jest mylący?** Obcięte osie Y, podwójne osie Y z różnymi skalami, efekty 3D na danych 2D i wybiórczo dobrane zakresy czasowe — wszystko to zniekształca percepcję. Rozwiązanie: rozpoczynanie osi Y od zera dla wykresów słupkowych, jawne etykietowanie osi i unikanie dekoracyjnych elementów zasłaniających dane. **Jak wybór palety kolorów wpływa na interpretację danych?** Palety sekwencyjne (od jasnego do ciemnego) nadają się do danych uporządkowanych, takich jak temperatura czy przychody. Palety dywergencyjne (dwa odcienie spotykające się w neutralnym środku) podkreślają odchylenia od punktu środkowego, np. zysk/strata lub współczynniki korelacji. Palety kategoryczne używają odrębnych odcieni dla niezwiązanych grup. Palety bezpieczne dla daltonistów (jak `colorblind` lub `muted` w Seaborn) zapewniają dostępność — szczegół wyróżniający doświadczonych kandydatów. **Jaka jest różnica między `plt.show()` a `plt.savefig()`?** `plt.show()` renderuje figurę w interaktywnym oknie i czyści stan figury po wyświetleniu. `plt.savefig()` zapisuje figurę do pliku bez czyszczenia jej. Wywołanie `savefig()` po `show()` generuje pusty plik — częsty błąd. Poprawna kolejność: najpierw `savefig()`, potem `show()`. ## Kompleksowe ćwiczenie rekrutacyjne Typowe zadanie domowe lub ćwiczenie live-coding łączy ładowanie danych, czyszczenie i wiele typów wykresów. Poniższy przykład odwzorowuje realne zadania rekrutacyjne z zespołów analitycznych. ```python # interview_exercise.py import matplotlib.pyplot as plt import seaborn as sns import pandas as pd import numpy as np sns.set_theme(style="whitegrid", palette="muted", font_scale=1.05) # Symulacja 12 miesięcy danych produktowych np.random.seed(42) months = pd.date_range("2025-01", periods=12, freq="MS") df = pd.DataFrame({ "month": months, "revenue": np.cumsum(np.random.normal(5000, 2000, 12)) + 50_000, "customers": np.cumsum(np.random.poisson(50, 12)) + 500, "churn_rate": np.clip(np.random.normal(0.05, 0.015, 12), 0.01, 0.12) }) fig, axes = plt.subplots(1, 3, figsize=(18, 5)) # Panel 1: Trend przychodów axes[0].plot(df["month"], df["revenue"], marker="o", color="#2563eb") axes[0].set_title("Revenue Trend") axes[0].set_ylabel("Revenue (USD)") axes[0].yaxis.set_major_formatter(plt.FuncFormatter(lambda x, _: f"${x:,.0f}")) axes[0].tick_params(axis="x", rotation=45) axes[0].spines[["top", "right"]].set_visible(False) # Panel 2: Wzrost klientów axes[1].bar(df["month"], df["customers"], color="#16a34a", width=20) axes[1].set_title("Customer Growth") axes[1].set_ylabel("Total Customers") axes[1].tick_params(axis="x", rotation=45) axes[1].spines[["top", "right"]].set_visible(False) # Panel 3: Wskaźnik churnu z linią progową axes[2].plot(df["month"], df["churn_rate"], marker="s", color="#dc2626") axes[2].axhline(y=0.05, color="gray", linestyle="--", label="Target: 5%") axes[2].set_title("Monthly Churn Rate") axes[2].set_ylabel("Churn Rate") axes[2].yaxis.set_major_formatter(plt.FuncFormatter(lambda x, _: f"{x:.1%}")) axes[2].tick_params(axis="x", rotation=45) axes[2].spines[["top", "right"]].set_visible(False) axes[2].legend() fig.suptitle("Product Dashboard — FY 2025", fontsize=14, fontweight="bold") plt.tight_layout() plt.savefig("interview_dashboard.png", dpi=150) plt.show() ``` To ćwiczenie demonstruje trzy typy wykresów w zunifikowanym układzie, prawidłowe formatowanie osi, linię referencyjną dla celów churnu i spójną stylizację. Są to dokładnie te elementy, które rekruterzy oceniają. ## Podsumowanie - Obiektowe API Matplotlib (`fig, ax = plt.subplots()`) daje pełną kontrolę i stanowi oczekiwany standard w środowiskach profesjonalnych i rekrutacyjnych - Parametr `hue` Seaborn i wbudowane funkcje statystyczne (KDE, mapy ciepła) obsługują analizę grupowaną przy minimalnej ilości kodu - Mapy ciepła korelacji z dywergencyjnymi mapami kolorów i stałymi skalami (`vmin=-1, vmax=1`) to podstawa rozmów kwalifikacyjnych z analityki - Należy zawsze wywoływać `savefig()` przed `show()`, aby uniknąć pustych plików wyjściowych - Czysta stylizacja — usunięte ramki, sformatowane etykiety ticków, jawne tytuły — sygnalizuje rekruterom myślenie na poziomie produkcyjnym - Warto ćwiczyć budowanie wielopanelowych dashboardów pod presją czasu: większość rund kodowania na żywo przeznacza 10-15 minut na zadanie wizualizacyjne --- Source: SharpSkill (https://sharpskill.dev), tech interview preparation for your real stack. HTML version of this page: https://sharpskill.dev/pl/blog/data-analytics/python-matplotlib-seaborn-data-visualization-interview