본문 바로가기
데이터분석/일상

벚꽃 시즌만 되면 비 오는 것 같은 느낌, 그저 기분 탓일까?

by 바른 곰 2025. 4. 20.

주제 선정 배경

3월에서 4월사이 연인들의 필수데이트 코스 벚꽃놀이, 저도 벚꽃구경을 좋아해서 석촌호수 같은 곳으로 매년 구경 가곤 합니다. 올해도 여자친구랑 혜화 낙산공원에 가서 꽃구경을 하고 왔는데요. 벚꽃은 언제봐도 로맨틱하고 예쁜 것 같습니다.

 

근데 올해 벚꽃이 피자마자 비가 오더라구요. 그때 뭔가 매년 벚꽃시즌만 되면 비가 내리는 것 같다는 느낌이 딱 들었습니다.

 

벚꽃시즌만 되면 비가 내리는 것 같은 이 느낌이 그저 기분탓일지, 아니면 실제로도 비가 매번 내리는지.
한번 확인해보려고 합니다.

활용 데이터

  • 벚꽃 개화시기 - 기상자료개방포털
    • 1973년부터 현재까지 벚꽃의 발아, 개화, 만발 시기를 기록한 데이터다. 벚꽃이 언제 피어났는지 확인하기 위해 수집했다.
  • 기상청_지상 일자료 조회서비스 API - 공공데이터포털
    • 과거의 기상정보 데이터를 API 형식으로 제공해준다. 과거 비온날을 확인하기 위해 수집하였다.

분석 과정 및 결론

 

먼저 벚꽃 개화시기 데이터를 이용해서 개화일을 기준으로 +6일간의 일강수량 정보를 기상청 API를 통해 수집했다. 아래는 개화일을 기준으로 +6일간의 일강수량 데이터를 수집한 것이다. 개화시기를 선정한 이유는 만발시기 데이터에 15개의 결측치가 있었기 때문이다. 반면 개화시기는 모든 연도에 관측 데이터가 존재했다.

 

이후 두 데이터를 연결하여 만발일을 기준으로 1주일간 비가 내린적이 며칠인지를 계산했다. 계산할 때 0mm 이상 즉, 비가 조금이라도 내린 날과 5mm 이상 즉, 벚꽃 구경에 방해가 될만큼 비가 적당히 내린 날과 10mm 이상 즉, 벚꽃이 떨어질만큼 강한 비가 내린 날 총 3가지로 분류했다.

 

벚꽃시즌만 되면 비오는 것 같은 느낌이 기분탓이었는지 확인하기 위해 내가 벚꽃구경을 가기 시작한 연도인 2016년부터 2025년까지 데이터를 이용해 확인해봤다. 아래는 2016~2025년 개화시기 이후 1주일 이내에 조금이라도 비가 온 년도, 5mm 이상, 10mm 이상 온 년도에 "비" 표시를 이용해 각각 시각화한 것이다.

 

 

2016년 ~ 2025년 전체 10년 중 개화 이후 조금이라도 비가 내린 해는 8년, 벚꽃구경에 방해가 될 정도인 5mm 이상 비가 내린 해는 5년, 벚꽃이 떨어질 정도로 강한 비가 내리는 정도인 10mm이상 비가 내린 해는 4년 이었다.

 

벚꽃 시즌만 되면 비오는 것 같은 느낌은 기분탓이 아니라
실제로 비가 거의 매번 내렸었다
.

쿠키

1973년부터 2025년까지 데이터를 살펴봤다.

 

1973년부터 현재까지 총 53년 중 벚꽃 개화 이후 1주일 이내에 조금이라도 비가 온 해는 44년 이었다. 즉, 대부분의 해에서 벚꽃 개화 이후 1주일 이내에 비가 내렸던 것을 알 수 있었다. 거의 매번 비가 조금이라도 왔다는 것이 놀라웠다.

 

 

1973년부터 현재까지 총 53년 중 벚꽃 개화 이후 1주일 이내에 벚꽃 구경에 방해가 되는 정도인 5mm이상 비가 온 해는 28년 이었다. 즉, 절반 정도의 해에서 벚꽃 개화 이후에 5mm 이상 비가 내렸던 것을 알 수 있었다.

 

 

1973년부터 현재까지 총 53년 중 벚꽃 개화 이후 1주일 이내에 벚꽃이 떨어질 정도인 10mm이상 비가 온 해는 23년 이었다. 즉, 전체 중 43% 정도의 해에서 벚꽃 개화 이후에 10mm 이상 비가 내렸던 것을 알 수 있었다.


마무리

벚꽃은 보통 3월 말 ~ 4월 초에 개화한다. 이 시기는 계절적으로 겨울철 고기압이 물러가고, 저기압과 봄비가 자주 찾아오는 시기라 비가 자주 내린다고 한다. 그래서 벚꽃 시즌이 되면 비가 자주 내린다고 생각했나보다. 그러므로 벚꽃이 피면 볼 수 있을 때 가서 봐야된다. 미루고 미루다 보면 비 때문에 그 해의 벚꽃을 놓칠지도 모른다.


최종코드

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

import requests
from datetime import datetime, timedelta
from tqdm import tqdm
# 데이터 불러오기
data = pd.read_excel('/content/drive/MyDrive/공모전/블로그/벚꽂 데이터/개화시기.xlsx')
data = data[['지점', '년도', '발아', '개화', '만발']]

# 데이터 타입 변환
data['개화'] = pd.to_datetime(data['개화'])


# 결측치 처리
data.loc[data['만발'] == '결측', '만발'] = 'Na'
data.loc[data['만발'] == ' ', '만발'] = 'Na'

data.head()
# 개화시기 이후 1주일간의 일강수량 데이터 추출
rain_data = pd.DataFrame()
url = 'http://apis.data.go.kr/1360000/AsosDalyInfoService/getWthrDataList'

for date in tqdm(data['개화']):
  startDt = date.strftime('%Y%m%d')
  endDt = (date + timedelta(days=6)).strftime('%Y%m%d')

  params ={
          'serviceKey' : 'API_KEY', #API 키 입력
          'pageNo' : '1',
          'numOfRows' : '10',
          'dataType' : 'JSON',
          'dataCd' : 'ASOS',
          'dateCd' : 'DAY',
          'startDt' : startDt,
          'endDt' : endDt,
          'stnIds' : '108'
          }

  response = requests.get(url, params=params)
  response = response.json()

  날짜_list = []
  일강수량_list = []

# 강수량 데이터 추출
  for idx in range(len(response['response']['body']['items']['item'])):
    날짜_list.append(response['response']['body']['items']['item'][idx]['tm'])
    일강수량_list.append(response['response']['body']['items']['item'][idx]['sumRn'])

  df = pd.DataFrame({
      '날짜' : 날짜_list,
      '일강수량' : 일강수량_list
  })

  rain_data = pd.concat([rain_data, df])

# 기상 데이터 전처리
rain_data = rain_data.reset_index(drop = True)
rain_data['날짜'] = pd.to_datetime(rain_data['날짜'])
rain_data.loc[rain_data['일강수량'] == '', '일강수량'] = 0
rain_data['일강수량'] = rain_data['일강수량'].astype('float')
rain_data.head()
# 강우일수 계산
data['개화이후강우일수'] = 0
data['개화이후10mm이상강우일수'] = 0

for idx in range(len(data)):
  tmp = rain_data.loc[rain_data['날짜'].dt.year == data['개화'][idx].year]
  data.loc[idx, '개화이후강우일수'] = len(tmp.loc[tmp['일강수량'] > 0])
  data.loc[idx, '개화이후10mm이상강우일수'] = len(tmp.loc[tmp['일강수량'] >= 10])

data.head()
# 2016 ~ 2025년 데이터 추출
df = data.copy()
df = df.loc[df['년도'] >= 2016] 
df['강우여부'] = df['개화이후강우일수'] != 0

# 시각화
fig, ax = plt.subplots(figsize=(10, 2))
ax.set_xlim(min(df['년도']) - 1, max(df['년도']) + 1)
ax.set_ylim(0, 1)
ax.axis('off')  # 축 숨기기

for idx, row in df.iterrows():
    x = row['년도']
    flower_icon = "꽃"
    rain_icon = "비" if row['강우여부'] else ""
    ax.text(x, 0.6, flower_icon, ha='center', fontsize=18)
    ax.text(x, 0.3, rain_icon, ha='center', fontsize=18)
    ax.text(x, 0, str(x), ha='center', fontsize=10)

plt.title("벚꽃 개화 이후 1주일 이내 조금이라도 비가 온 해", fontsize=14)
plt.tight_layout()
plt.show()
# 전체 데이터 이용
df = data.copy()
df['강우여부'] = df['개화이후강우일수'] != 0

# 시각화
fig, ax = plt.subplots(figsize=(22, 2))
ax.set_xlim(min(df['년도']) - 1, max(df['년도']) + 1)
ax.set_ylim(0, 1)
ax.axis('off')  # 축 숨기기

for idx, row in df.iterrows():
    x = row['년도']
    flower_icon = "꽃"
    rain_icon = "비" if row['강우여부'] else ""
    ax.text(x, 0.6, flower_icon, ha='center', fontsize=18)
    ax.text(x, 0.3, rain_icon, ha='center', fontsize=18)
    ax.text(x, 0, str(x), ha='center', fontsize=10)

plt.title("벚꽃 개화 이후 1주일 이내 0mm 이상 비가 온 해", fontsize=14)
plt.tight_layout()
plt.show()