250811 [ Day 26 ] - Seaborn, BeautifulSoup (1)

TaeHyun·2025년 8월 11일

TIL

목록 보기
26/188

시작하며

오늘도 Seaborn으로 만든 많은 그래프 이미지를 정리하면서 블로그를 쓰는 순간이 걱정됐다. 일단 이미지 세팅을 따로 저장해 두고 계속 복사하면서 작성해봐야겠다.

Seaborn

  • Matplotlib 기반의 시각화 라이브러리
  • 복잡한 그래프를 간단한 코드로 작성
  • 통계적 데이터 시각화에 특화(Pandas와 연계 좋음)
import seaborn as sns
import matplotlib.pyplot as plt

sns.__version__

데이터셋 불러오기

  • 사용 가능한 데이터셋 이름 출력
sns.get_dataset_names()

  • 데이터셋 불러오기
df = sns.load_dataset("car_crashes")
df.head()

스타일 및 폰트 설정

  • 사용 가능한 폰트 목록 보기
import matplotlib.font_manager as fm

for f in fm.fontManager.ttflist:
    print(f.name)

  • 테마 스타일 설정

  • sns.set_style() : 스타일 테마 설정

    • “white”, “dark”, “whitegrid”, “darkgrid”, “ticks”
  • sns.set_context() : 문맥에 따라 스타일 크기 조정

    • “paper” : 논문 / 출판용
    • “notebook” : Jupyter 기본값
    • “talk” : 프레젠테이션용
    • “poster” : 포스터 등 대형 디스플레이용
  • sns.set_palette() : 색상 팔레트 설정

    • 범주형 : "deep", "muted", "bright", "pastel", "dark", "colorblind”
    • 연속형 : "rocket", "mako", "coolwarm", "viridis", "flare" 등
sns.set_style("white")
sns.set_context("notebook")
sns.set_palette("muted")
# 이후 폰트 깨짐 방지 설정

# 한글 깨짐 방지

# Windows에서 한글 폰트 설정
plt.rcParams['font.family'] = 'Malgun Gothic'  # '맑은 고딕'이 설치되어 있을 경우
plt.rcParams['axes.unicode_minus'] = False     # 마이너스(-) 부호 깨짐 방지

# macOS에서 한글 폰트 설정
plt.rcParams['font.family'] = 'AppleGothic'   # macOS 기본 한글 폰트
plt.rcParams['axes.unicode_minus'] = False

범주형 데이터 그래프

countplot()

palette = sns.color_palette("deep")
tips = sns.load_dataset("tips")

sns.countplot(data=tips, x="day", hue="sex", edgecolor="black", palette=palette)

plt.title("요일별 방문자수", size=15, pad=20)
plt.grid(linestyle=":", alpha=0.7)
plt.ylabel("count", rotation=0, labelpad=25)

plt.show()


barplot()

  • 각 범주의 평균값을 막대로 표현
  • 신뢰구간을 함께 시각화
palette = sns.color_palette("pastel6")
sns.barplot(data=tips, x="day", y="tip", palette=palette, saturation=1, width=0.5, linewidth=1)

plt.title("요일별 평균 팁 금액")
plt.grid(linestyle=":", alpha=0.7)
plt.ylabel("tip", rotation=0, labelpad=20)

plt.show()


boxplot()

  • 분포 + 사분위수 + 이상치 시각화
  • 데이터 탐색에 자주 사용
sns.set_theme(style="whitegrid")
plt.figure(figsize=(8, 6))
sns.boxplot(data=tips, x="day", y="total_bill", hue="sex", palette="Set2")

plt.title("Boxplot of Total Bill by Day and Sex", fontsize=14)
plt.xlabel("Day of the Week")
plt.ylabel("Total Bill ($)")
plt.legend(title="Sex")
plt.tight_layout()

plt.show()


violinplot()

  • boxplot + 커널 밀도(kde)
plt.subplot(1, 3, 1)
sns.violinplot(data=tips, x="day", y="total_bill")
plt.figure(figsize=(15, 5))
plt.title("Violinplot")

plt.show()


stripplot()

  • 각 데이터 포인트를 작은 점으로 표현
    • 데이터가 많으면 점이 겹쳐서 밀집된 부분이 뭉쳐 보임

    • 작은 데이터셋에서 개별 값 확인에 유용

      plt.subplot(1, 3, 2)
      sns.stripplot(data=tips, x="day", y="total_bill", jitter=True)
      plt.figure(figsize=(15, 5))
      plt.title("Stripplot")
      
      plt.show()


swarmplot()

  • stripplot 과 비슷하지만, 점이 겹치지 않게 자동으로 퍼짐
  • 개별 값 + 분포 밀집도를 동시에 파악 가능
sns.swarmplot(data=tips, x="day", y="total_bill", hue="sex", palette="Set2", size=6)

plt.title("Swarmplot of Total Bill by Day and Sex", fontsize=14)
plt.xlabel("Day of the Week")
plt.ylabel("Total Bill ($)")
plt.legend(title="Sex")
plt.tight_layout()

plt.show()


수치형 데이터 그래프

displot()

  • 히스토그램 + 커널 밀도(kde)
  • kde=True로 하면 kde 그래프 생성
sns.displot(data=tips, x="total_bill", edgecolor="black", alpha=0.5, kde=True, bins=20)

plt.title("Total bill")
plt.grid(linestyle=":", alpha=0.7)
plt.ylabel("count", rotation=0, labelpad=25)
plt.xlabel("total_bill", labelpad=10)

plt.show()


histplot()

plt.figure(figsize=(18, 5))
plt.subplot(1, 3, 1)
sns.histplot(data=tips, x="total_bill", bins=20,hue="sex", multiple="stack", palette="Set2")

plt.title("Histplot")

plt.show()


kdeplot()

  • 커널 밀도 그래프
plt.figure(figsize=(18, 5))
plt.subplot(1, 3, 2)
sns.kdeplot(data=tips, x="total_bill", hue="sex", fill=True, palette="Set2")
plt.title("KDEplot")

plt.show()


rugplot()

  • 각 데이터 포인트를 작은 선으로 표시
  • kdeplot이나 histplot과 함께 사용하면 효과적
plt.figure(figsize=(18, 5))
plt.subplot(1, 3, 3)
sns.kdeplot(data=tips, x="total_bill", fill=True, color="skyblue", alpha=0.4)
sns.rugplot(data=tips, x="total_bill", hue="sex", palette="Set2")

plt.title("Rugplot + KDEplot")

plt.show()


관계형 데이터 그래프

scatterplot()

  • 두 변수 간의 관계를 점으로 표현한 그래프 (산점도)
  • 연속형 데이터 간의 상관관계를 시각적으로 파악할 때 유용
palette = sns.color_palette("pastel6")
sns.scatterplot(data=tips, x="total_bill", y="tip", hue="sex", palette=palette)
plt.grid(linestyle=":", alpha=0.7)
plt.ylabel("tip", rotation=0, labelpad=20)

plt.show()


lineplot()

  • 연속형 데이터의 변화를 선 그래프로 시각화
  • 기본적으로 x축은 독립변수, y축은 종속변수
plt.figure(figsize=(8,5))
sns.lineplot(data=tips, x="size", y="total_bill", hue="sex", style="sex", markers=True, dashes=False, palette="Set2")

plt.title("Lineplot Example")

plt.show()


relplot()

  • 범용 관계형 그래프
  • kind="line" : 선 그래프
  • kind="scatter" : 산점도
plt.figure(figsize=(8,5))
sns.relplot(data=tips, x="size", y="total_bill", hue="sex", col="day", kind="line", markers=True, dashes=False, palette="Set2", height=4, aspect=1)

plt.show()


다변량 시각

pairplot()

  • 모든 변수 간의 관계를 산점도와 히스토그램으로 시각화
  • 전체적으로 살펴볼 때 유용
sns.pairplot(data=penguins, hue="species", palette="Set2")

plt.show()


heatmap()

  • 데이터를 색상으로 표현하는 그래프
  • 상관계수 시각화에 자주 사용
  • 상관계수 행렬 = corr = penguins.corr(numeric_only=True)
corr = penguins.corr(numeric_only=True)

sns.heatmap(corr, annot=True, fmt=".2f", cmap="coolwarm", square=False)
plt.xticks(rotation=45)

plt.show()


jointplot()

  • 두 변수의 관계를 중앙에 산점도, 선그래프로 양쪽에 분포 그래프로 동시에 표현
sns.jointplot(data=penguins, x="flipper_length_mm", y="body_mass_g", kind="hex", cmap="viridis")

plt.show()


jointplot(kind="reg")

  • 산점도와 함께 선형 회귀선을 그려 신뢰구간 표시
palette = sns.color_palette("pastel6")
sns.jointplot(data=penguins, x="flipper_length_mm", y="body_mass_g", kind="reg", palette=palette)
plt.ylabel("body_mass_g", rotation=0, labelpad=40)
plt.grid(linestyle=":", alpha=0.7)

plt.show()


BeautifulSoup

  • HTML과 XML파일에서 데이터를 추출하기 위한 라이브러리
from bs4 import BeautifulSoup
import requests

soup 객체 생성

soup = BeautifulSoup(html_data, "lxml")
print(soup.prettify())
  • “lxml” : HTML과 XML 파일을 위한 Parser
  • “html.parser” : HTML용 내장 Parser

데이터 선택

find()

  • 첫번째 매칭 요소 선택
  • 태그를 기준으로 탐색
result = soup.find("h1")

print(result)
# <h1 class="" title="">Hello BeautifulSoup</h1>
print(result.text)
# Hello BeautifulSoup
print(result.get_text())
# Hello BeautifulSoup

  • 속성 조건으로 검색
result = soup.find("h1", class_="sub_title")
print(result.text)
# 안녕 아름다운 수프

find_all()

  • 모든 매칭 요소 선택
result = soup.find_all("h1")
print(result)
# [<h1 class="title">Hello BeautifulSoup</h1>, <h1 class="sub_title">안녕 아름다운 수프</h1>]

for i in result:
    print(i.text)
# Hello BeautifulSoup
# 안녕 아름다운 수프

select()

  • 모든 매칭 요소 선택
  • CSS 선택자로 탐색
result = soup.select("ul.items")
print(result)
# [<ul class="items">
# <li data-id="1">사과</li>
# <li data-id="2">바나나</li>
# <li data-id="3">체리</li>
# </ul>, <ul class="items">
# <li data-id="1">python</li>
# <li data-id="2">c++</li>
# <li data-id="3">SQL</li>
# </ul>]

for i in result:
    print(i.text)
# 사과
# 바나나
# 체리

# python
# c++
# SQL

select_one()

  • 첫번째 매칭 요소 선택
result = soup.select_one("ul.items")
print(result)
# <ul class="items">
# <li data-id="1">사과</li>
# <li data-id="2">바나나</li>
# <li data-id="3">체리</li>
# </ul>

requests와 함께 사용법

  • 웹 사이트에서 데이터를 송수신 할 수 있는 라이브러리

headers

  • 봇으로 인식하고 차단하는 기능 방지
headers = {
    "User-Agent": "Mozilla/5.0"
}
response = requests.get(url, headers=headers)

.get()

  • 지정한 url로 HTTP Get 요청을 보냄
  • 서버에서 데이터를 가져올 때 주로 사용

.status_code

  • 서버가 요청에 대해 응답한 HTTP 상태 코드를 표시
    • 200 : 성공
    • 404 : 페이지 없음
    • 500 : 서버 오류

.content

  • 서버에서 받은 응답 본문을 바이트 형태로 반환

마치며

오늘은 이미지 작업이 꽤나 수월했다. 이미지를 정렬하고 사이즈를 조절하면 이상하게 줄바꿈을 했을때 2칸 들여쓰기가 돼서 글을 쓰거나 파트별로 줄바꿈을 할 때 불편했는데 줄바꿈과 틀을 다 잡아두고 이미지를 정리하니까 그런 불편함이 많이 줄었다.

NOTION

MY NOTION (Seaborn)

profile
Hello I'm TaeHyunAn, Currently Studying Data Analysis

0개의 댓글