8  Podstawowe typy wykresów

Dobry wykres jest wart więcej niż tabela z setkami liczb. W tej sekcji nauczymy się tworzyć cztery najważniejsze typy wykresów w analizie ekonomicznej.

NoteGramatyka wykresów

Oba środowiska (R/Python) mają swoje podejście do tworzenia wykresów:

  • R / ggplot2 — opiera się na gramatyce wykresów (Grammar of Graphics). Wykres budujesz warstwami: dane → geometria (linia, słupki, punkty) → skale → etykiety.
  • Python / matplotlib + seabornseaborn to uproszczone API dla typowych wykresów statystycznych; matplotlib daje pełną kontrolę nad każdym detalem.

8.1 Wykres liniowy — szeregi czasowe

Idealny do danych ekonomicznych zmieniających się w czasie.

library(ggplot2)
library(dplyr)

dane_ekon <- data.frame(
  rok          = 2015:2024,
  PKB          = c(1800, 1862, 1984, 2120, 2292, 2330, 2625, 2780, 2900, 3070),
  inflacja     = c(2.1, 1.3, -0.6, 1.6, 1.8, 2.3, 5.1, 14.4, 11.4, 3.6),
  stopa_bezrob = c(7.5, 6.2, 5.5, 4.9, 3.8, 3.3, 5.6, 3.4, 2.9, 2.8)
)

# Prosty wykres liniowy
ggplot(dane_ekon, aes(x = rok, y = inflacja)) +
  geom_line(color = "steelblue", linewidth = 1) +
  geom_point(color = "steelblue", size = 3) +
  labs(
    title = "Inflacja w Polsce (2015–2024)",
    x = "Rok",
    y = "Inflacja (%)"
  ) +
  theme_minimal()

# Dwie linie — reshape danych do formatu długiego
library(tidyr)

dane_dlugi <- dane_ekon |>
  select(rok, inflacja, stopa_bezrob) |>
  pivot_longer(cols = -rok, names_to = "wskaznik", values_to = "wartosc")

ggplot(dane_dlugi, aes(x = rok, y = wartosc, color = wskaznik)) +
  geom_line(linewidth = 1) +
  geom_point(size = 2) +
  scale_color_manual(
    values = c("inflacja" = "#d62728", "stopa_bezrob" = "#1f77b4"),
    labels = c("Inflacja (%)", "Stopa bezrobocia (%)")
  ) +
  labs(title = "Inflacja i bezrobocie w Polsce",
       x = "Rok", y = "Wartość (%)", color = NULL) +
  theme_minimal() +
  theme(legend.position = "bottom")

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

sns.set_style("whitegrid")

dane_ekon = pd.DataFrame({
    "rok":          list(range(2015, 2025)),
    "PKB":          [1800, 1862, 1984, 2120, 2292, 2330, 2625, 2780, 2900, 3070],
    "inflacja":     [2.1, 1.3, -0.6, 1.6, 1.8, 2.3, 5.1, 14.4, 11.4, 3.6],
    "stopa_bezrob": [7.5, 6.2, 5.5, 4.9, 3.8, 3.3, 5.6, 3.4, 2.9, 2.8]
})

# Prosty wykres liniowy
fig, ax = plt.subplots(figsize=(9, 5))
ax.plot(dane_ekon["rok"], dane_ekon["inflacja"],
        color="steelblue", linewidth=2, marker="o", markersize=5)
ax.set_title("Inflacja w Polsce (2015–2024)", fontsize=14)
ax.set_xlabel("Rok")
ax.set_ylabel("Inflacja (%)")
ax.grid(True, alpha=0.4)
plt.tight_layout()
plt.show()
# Dwie linie na jednym wykresie
fig, ax = plt.subplots(figsize=(9, 5))
ax.plot(dane_ekon["rok"], dane_ekon["inflacja"],
        color="#d62728", linewidth=2, marker="o", markersize=5,
        label="Inflacja (%)")
ax.plot(dane_ekon["rok"], dane_ekon["stopa_bezrob"],
        color="#1f77b4", linewidth=2, marker="s", markersize=5,
        label="Stopa bezrobocia (%)")
ax.set_title("Inflacja i bezrobocie w Polsce", fontsize=14)
ax.set_xlabel("Rok")
ax.set_ylabel("Wartość (%)")
ax.legend()
ax.grid(True, alpha=0.4)
plt.tight_layout()
plt.show()

8.2 Wykres słupkowy — porównanie kategorii

wydatki <- data.frame(
  kategoria   = c("Ochrona zdrowia", "Edukacja", "Obrona",
                  "Transport", "Kultura", "Administracja"),
  procent_PKB = c(4.8, 5.0, 2.4, 1.9, 0.7, 2.1)
)

ggplot(wydatki, aes(x = reorder(kategoria, procent_PKB), y = procent_PKB)) +
  geom_col(fill = "steelblue", width = 0.7) +
  coord_flip() +
  labs(title = "Wydatki publiczne według kategorii",
       subtitle = "jako % PKB", x = NULL, y = "% PKB") +
  theme_minimal() +
  ylim(0, 6.5)

wydatki = pd.DataFrame({
    "kategoria":   ["Ochrona zdrowia", "Edukacja", "Obrona",
                    "Transport", "Kultura", "Administracja"],
    "procent_PKB": [4.8, 5.0, 2.4, 1.9, 0.7, 2.1]
}).sort_values("procent_PKB")

fig, ax = plt.subplots(figsize=(8, 5))
bars = ax.barh(wydatki["kategoria"], wydatki["procent_PKB"],
               color="steelblue", height=0.6)

ax.set_title("Wydatki publiczne według kategorii\njako % PKB", fontsize=13)
ax.set_xlabel("% PKB")
ax.set_xlim(0, 6.5)
ax.grid(axis="x", alpha=0.4)
plt.tight_layout()
plt.show()

8.3 Histogram i wykres gęstości — rozkład zmiennej

set.seed(42)
dochody <- data.frame(
  dochod = c(rnorm(300, mean = 4500, sd = 800),
             rnorm(100, mean = 9000, sd = 1200)),
  grupa  = c(rep("Pracownicy", 300), rep("Menedżerowie", 100))
)

ggplot(dochody, aes(x = dochod, fill = grupa)) +
  geom_histogram(aes(y = after_stat(density)),
                 bins = 40, alpha = 0.5, position = "identity") +
  geom_density(alpha = 0) +
  scale_fill_manual(values = c("#1f77b4", "#d62728")) +
  labs(title = "Rozkład dochodów według grupy pracowników",
       x = "Miesięczny dochód brutto (PLN)", y = "Gęstość", fill = "Grupa") +
  theme_minimal()

import numpy as np

np.random.seed(42)
dochody = pd.DataFrame({
    "dochod": np.concatenate([
        np.random.normal(4500, 800, 300),
        np.random.normal(9000, 1200, 100)
    ]),
    "grupa": ["Pracownicy"] * 300 + ["Menedżerowie"] * 100
})

fig, ax = plt.subplots(figsize=(9, 5))
for grupa, kolor in [("Pracownicy", "#1f77b4"), ("Menedżerowie", "#d62728")]:
    dane_g = dochody[dochody["grupa"] == grupa]["dochod"]
    ax.hist(dane_g, bins=40, density=True, alpha=0.5, color=kolor, label=grupa)
    sns.kdeplot(dane_g, color=kolor, ax=ax, linewidth=2)

ax.set_title("Rozkład dochodów według grupy pracowników", fontsize=13)
ax.set_xlabel("Miesięczny dochód brutto (PLN)")
ax.set_ylabel("Gęstość")
ax.legend()
ax.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()

8.4 Wykres punktowy — zależności między zmiennymi

ggplot(dane_ekon, aes(x = PKB, y = inflacja, label = rok)) +
  geom_point(size = 4, color = "steelblue", alpha = 0.8) +
  geom_smooth(method = "lm", se = TRUE,
              color = "red", linetype = "dashed") +
  geom_text(nudge_y = 0.4, size = 3, color = "gray30") +
  labs(title   = "Zależność między PKB a inflacją",
       x       = "PKB (mld PLN)",
       y       = "Inflacja (%)",
       caption = "Wstęga = 95% przedział ufności") +
  theme_minimal()

fig, ax = plt.subplots(figsize=(8, 5))
ax.scatter(dane_ekon["PKB"], dane_ekon["inflacja"],
           s=80, color="steelblue", alpha=0.8, zorder=5)

for _, row in dane_ekon.iterrows():
    ax.annotate(str(int(row["rok"])),
                (row["PKB"], row["inflacja"]),
                textcoords="offset points", xytext=(5, 5),
                fontsize=8, color="gray")

z = np.polyfit(dane_ekon["PKB"], dane_ekon["inflacja"], 1)
p = np.poly1d(z)
x_t = np.linspace(dane_ekon["PKB"].min(), dane_ekon["PKB"].max(), 100)
ax.plot(x_t, p(x_t), "r--", alpha=0.7, label="Trend liniowy")

ax.set_title("Zależność między PKB a inflacją", fontsize=13)
ax.set_xlabel("PKB (mld PLN)")
ax.set_ylabel("Inflacja (%)")
ax.legend()
ax.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()