1. 전지구의 해수면 수온편차 자료 구하기
Optimum Interpolation Sea Surface Temperature (OISST)
The NOAA 1/4° Daily Optimum Interpolation Sea Surface Temperature (OISST) is a long term Climate Data Record that incorporates observations from different platforms (satellites, ships, buoys and Argo floats) into a regular global grid. The dataset is i
www.ncei.noaa.gov
[NetCDF] 클릭 > 엘니뇨에 해당하는 날짜 검색((예시)1981.09.01.) 후 자료 다운로드(파일 이름 잘 확인해둘 것) >구글코랩에 데이터 업로드
2. 생성형 AI (ChatGPT)를 활용하여 질문하기
1) 첫번째 질문 : 19810910 파일을 통해 동, 서태평양의 수온 편차를 지도에 나타내고 싶어.
import xarray as xr
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import cartopy.feature as cfeature
import matplotlib.patches as mpatches
# ▶ NetCDF 파일 열기
ds = xr.open_dataset('oisst-avhrr-v02r01.19810901.nc')
# ▶ anomaly 변수 선택 (시간 차원이 1개뿐이므로 [0]으로 접근)
anom = ds['anom'][0] # 단위: °C
# ▶ 지도 설정 (태평양 중심)
fig = plt.figure(figsize=(14, 6))
ax = plt.axes(projection=ccrs.PlateCarree(central_longitude=180))
# ▶ 해수면 온도 편차 색상 시각화
plot = anom.plot.pcolormesh(
ax=ax,
transform=ccrs.PlateCarree(),
cmap='RdBu_r',
vmin=-5,
vmax=5,
add_colorbar=False
)
# ▶ 컬러바 추가
cbar = plt.colorbar(plot, ax=ax, orientation='vertical', pad=0.05, aspect=40)
cbar.set_label('SST Anomaly (°C)', fontsize=12)
# ▶ 해안선, 국가 경계 추가
ax.coastlines()
ax.add_feature(cfeature.BORDERS, linewidth=0.5)
# ▶ 제목 추가
ax.set_title('Global Sea Surface Temperature Anomaly\n1981-09-01 (AVHRR OISST v2.1)', fontsize=14)
# ▶ 동태평양(East Pacific) 영역 박스 표시 (170°W~120°W, 5°S~5°N)
east_box = mpatches.Rectangle(
xy=(-170, -5), width=50, height=10,
edgecolor='black', facecolor='none',
transform=ccrs.PlateCarree(), linewidth=1.5, linestyle='--'
)
ax.add_patch(east_box)
ax.text(-145, 6, 'Niño 3.4 Region (East Pacific)', fontsize=9, transform=ccrs.PlateCarree())
# ▶ 서태평양(West Pacific) 텍스트 표시
ax.text(140, 6, 'West Pacific', fontsize=9, transform=ccrs.PlateCarree())
# ▶ 범례 추가: Niño 3.4 박스 설명용
east_legend = mpatches.Patch(edgecolor='black', facecolor='none', hatch='//', label='Niño 3.4 Region (170°W~120°W)', linestyle='--')
plt.legend(handles=[east_legend], loc='lower left', fontsize=9, frameon=True)
plt.tight_layout()
plt.show()
위 코드를 돌려보면 오류가 발생함. 따라서 두번째 질문을 실시.
2) 두번째 질문 : 다음 오류가 발생했어. 코드를 수정해줘.
ValueError Traceback (most recent call last) <ipython-input-5-1142853077> in <cell line: 0>() 16 17 # ▶ 해수면 온도 편차 색상 시각화 ---> 18 plot = anom.plot.pcolormesh( 19 ax=ax, 20 transform=ccrs.PlateCarree(), 2 frames /usr/local/lib/python3.11/dist-packages/xarray/plot/utils.py in _infer_xy_labels(darray, x, y, imshow, rgb) 410 if x is None and y is None: 411 if darray.ndim != 2: --> 412 raise ValueError("DataArray must be 2d") 413 y, x = darray.dims 414 elif x is None: ValueError: DataArray must be 2d
import xarray as xr
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import cartopy.feature as cfeature
import matplotlib.patches as mpatches
# ▶ NetCDF 파일 열기
ds = xr.open_dataset('oisst-avhrr-v02r01.19810901.nc')
# ▶ anomaly 데이터 선택 및 2차원으로 차원 축소
anom = ds['anom'].isel(time=0) # 또는 ds['anom'].squeeze()
# ▶ 지도 설정 (태평양 중심)
fig = plt.figure(figsize=(14, 6))
ax = plt.axes(projection=ccrs.PlateCarree(central_longitude=180))
# ▶ 해수면 온도 편차 색상 시각화
plot = anom.plot.pcolormesh(
ax=ax,
transform=ccrs.PlateCarree(),
cmap='RdBu_r',
vmin=-5,
vmax=5,
add_colorbar=False
)
# ▶ 컬러바 추가
cbar = plt.colorbar(plot, ax=ax, orientation='vertical', pad=0.05, aspect=40)
cbar.set_label('SST Anomaly (°C)', fontsize=12)
# ▶ 해안선, 국가 경계 추가
ax.coastlines()
ax.add_feature(cfeature.BORDERS, linewidth=0.5)
# ▶ 제목 추가
ax.set_title('Global Sea Surface Temperature Anomaly\n1981-09-01 (AVHRR OISST v2.1)', fontsize=14)
# ▶ 동태평양(Niño 3.4 Region) 박스 표시
east_box = mpatches.Rectangle(
xy=(-170, -5), width=50, height=10,
edgecolor='black', facecolor='none',
transform=ccrs.PlateCarree(), linewidth=1.5, linestyle='--'
)
ax.add_patch(east_box)
ax.text(-145, 6, 'Niño 3.4 Region (East Pacific)', fontsize=9, transform=ccrs.PlateCarree())
# ▶ 서태평양 텍스트 표시
ax.text(140, 6, 'West Pacific', fontsize=9, transform=ccrs.PlateCarree())
# ▶ 범례 추가
east_legend = mpatches.Patch(edgecolor='black', facecolor='none', hatch='//', label='Niño 3.4 Region (170°W~120°W)', linestyle='--')
plt.legend(handles=[east_legend], loc='lower left', fontsize=9, frameon=True)
plt.tight_layout()
plt.show()
그러나 또 다시 오류가 발생함. 따라서 세번째 질문을 실시
3) 세번째 질문: 또 오류가 발생했어.
import xarray as xr
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import cartopy.feature as cfeature
import matplotlib.patches as mpatches
# ▶ NetCDF 파일 열기
ds = xr.open_dataset('oisst-avhrr-v02r01.19810901.nc')
# ▶ anomaly 변수에서 시간 차원 제거 + squeeze (2D 보장)
anom = ds['anom'].isel(time=0).squeeze()
# ▶ lat/lon 차원 이름 확인 (안전용)
print("Dimensions:", anom.dims)
# ▶ 지도 설정
fig = plt.figure(figsize=(14, 6))
ax = plt.axes(projection=ccrs.PlateCarree(central_longitude=180))
# ▶ 해수면 온도 편차 색상 시각화
plot = anom.plot.pcolormesh(
ax=ax,
x='lon', # x축은 경도
y='lat', # y축은 위도
transform=ccrs.PlateCarree(),
cmap='RdBu_r',
vmin=-5,
vmax=5,
add_colorbar=False
)
# ▶ 컬러바 추가
cbar = plt.colorbar(plot, ax=ax, orientation='vertical', pad=0.05, aspect=40)
cbar.set_label('SST Anomaly (°C)', fontsize=12)
# ▶ 지도 요소 추가
ax.coastlines()
ax.add_feature(cfeature.BORDERS, linewidth=0.5)
ax.set_title('Global SST Anomaly - 1981-09-01 (AVHRR OISST v2.1)', fontsize=14)
# ▶ 동태평양(Niño 3.4 Region) 영역 표시
east_box = mpatches.Rectangle(
xy=(-170, -5), width=50, height=10,
edgecolor='black', facecolor='none',
transform=ccrs.PlateCarree(), linewidth=1.5, linestyle='--'
)
ax.add_patch(east_box)
ax.text(-145, 6, 'Niño 3.4 Region (East Pacific)', fontsize=9, transform=ccrs.PlateCarree())
# ▶ 서태평양 텍스트
ax.text(140, 6, 'West Pacific', fontsize=9, transform=ccrs.PlateCarree())
# ▶ 범례 추가
east_legend = mpatches.Patch(edgecolor='black', facecolor='none', hatch='//', label='Niño 3.4 Region', linestyle='--')
plt.legend(handles=[east_legend], loc='lower left', fontsize=9, frameon=True)
plt.tight_layout()
plt.show()

4) 네번째 질문: 엘니뇨가 엄청 심한 날짜를 하나 골라줘. nc 파일을 다시 받아야 겠어.
20151120을 추천받아 Index of /data/sea-surface-temperature-optimum-interpolation/v2.1/access/avhrr/201511 사이트에서 nc파일을 다운받음. 이후 코랩에 업로드하여 다음 코드를 실행.

import xarray as xr
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import cartopy.feature as cfeature
import matplotlib.patches as mpatches
# ▶ 2015년 엘니뇨 시기 NetCDF 파일 열기
ds = xr.open_dataset('oisst-avhrr-v02r01.20151120.nc')
# ▶ anomaly 변수 선택 및 2차원 차원으로 축소
anom = ds['anom'].isel(time=0).squeeze()
# ▶ 지도 설정 (태평양 중심)
fig = plt.figure(figsize=(14, 6))
ax = plt.axes(projection=ccrs.PlateCarree(central_longitude=180))
# ▶ anomaly 데이터 시각화
plot = anom.plot.pcolormesh(
ax=ax,
x='lon', y='lat', # 축 명시
transform=ccrs.PlateCarree(),
cmap='RdBu_r',
vmin=-5, vmax=5,
add_colorbar=False
)
# ▶ 컬러바 추가
cbar = plt.colorbar(plot, ax=ax, orientation='vertical', pad=0.05, aspect=40)
cbar.set_label('SST Anomaly (°C)', fontsize=12)
# ▶ 해안선 및 국가 경계
ax.coastlines()
ax.add_feature(cfeature.BORDERS, linewidth=0.5)
# ▶ 제목
ax.set_title('Global Sea Surface Temperature Anomaly\n2015-11-20 (AVHRR OISST v2.1)', fontsize=14)
# ▶ Niño 3.4 영역 표시 (170°W ~ 120°W, 5°S ~ 5°N → 즉 -170 ~ -120)
east_box = mpatches.Rectangle(
xy=(-170, -5), width=50, height=10,
edgecolor='black', facecolor='none',
transform=ccrs.PlateCarree(), linewidth=1.5, linestyle='--'
)
ax.add_patch(east_box)
ax.text(-145, 6, 'Niño 3.4 Region (East Pacific)', fontsize=9, transform=ccrs.PlateCarree())
# ▶ 서태평양 텍스트 표시
ax.text(140, 6, 'West Pacific', fontsize=9, transform=ccrs.PlateCarree())
# ▶ 범례 박스 추가
east_legend = mpatches.Patch(edgecolor='black', facecolor='none', label='Niño 3.4 Region', linestyle='--')
plt.legend(handles=[east_legend], loc='lower left', fontsize=9, frameon=True)
plt.tight_layout()
plt.show()

5) 다섯번째 질문: 지금 지구를 다 펼쳐놨잖아. 이 지도 말고 동그란 지구에 표현하고 싶어.
import xarray as xr
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import cartopy.feature as cfeature
# ▶ NetCDF 파일 열기 (2015년 11월 20일 엘니뇨 절정기)
ds = xr.open_dataset('oisst-avhrr-v02r01.20151120.nc')
anom = ds['anom'].isel(time=0).squeeze()
# ▶ 둥근 지구 투영 설정 (Orthographic, 중심: 태평양)
projection = ccrs.Orthographic(central_longitude=180, central_latitude=0)
# ▶ 시각화
fig = plt.figure(figsize=(10, 10))
ax = plt.axes(projection=projection)
# ▶ anomaly 시각화
anom.plot.pcolormesh(
ax=ax,
x='lon', y='lat',
transform=ccrs.PlateCarree(),
cmap='RdBu_r',
vmin=-5, vmax=5,
add_colorbar=True,
cbar_kwargs={'label': 'SST Anomaly (°C)'}
)
# ▶ 지도 꾸미기
ax.coastlines()
ax.gridlines(draw_labels=False)
ax.set_title('Sea Surface Temperature Anomaly (Orthographic)\n2015-11-20', fontsize=14)
plt.tight_layout()
plt.show()

6) 여섯번째 질문: 동태평양에 남아메리카 지역도 같이 나오게 수정하고, Nino3.4지역을 대략적으로 표시 가능할까?
import xarray as xr
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import cartopy.feature as cfeature
import matplotlib.patches as mpatches
# ▶ 데이터 열기
ds = xr.open_dataset('oisst-avhrr-v02r01.20151120.nc')
anom = ds['anom'].isel(time=0).squeeze()
# ▶ Orthographic 투영 (동태평양+남아메리카 중심)
projection = ccrs.Orthographic(central_longitude=-140, central_latitude=0)
# ▶ 시각화 시작
fig = plt.figure(figsize=(10, 10))
ax = plt.axes(projection=projection)
# ▶ SST anomaly 색상 표시
plot = anom.plot.pcolormesh(
ax=ax,
x='lon', y='lat',
transform=ccrs.PlateCarree(),
cmap='RdBu_r',
vmin=-5, vmax=5,
add_colorbar=True,
cbar_kwargs={'label': 'SST Anomaly (°C)'}
)
# ▶ 지도 요소
ax.coastlines()
ax.add_feature(cfeature.BORDERS, linewidth=0.5)
ax.gridlines(draw_labels=False)
ax.set_title('SST Anomaly with Niño 3.4 Region\n2015-11-20 (Orthographic)', fontsize=14)
# ▶ Niño 3.4 영역 박스 (170°W~120°W == -170~ -120, 위도 -5°~5°)
nino_box = mpatches.Rectangle(
xy=(-170, -5), width=50, height=10,
edgecolor='black',
facecolor='none',
linewidth=2,
linestyle='--',
transform=ccrs.PlateCarree()
)
ax.add_patch(nino_box)
# ▶ Niño 3.4 텍스트 추가
ax.text(-150, 8, 'Niño 3.4', fontsize=10, color='black', transform=ccrs.PlateCarree())
plt.tight_layout()
plt.show()

사이트에서 하나의 기간이 아닌 여러 기간 동안의 자료가 있기 때문에 엘니뇨가 강화되는 모습까지 시뮬레이션 해볼 수 있다고 한다. chatGPT 한테 질문을 잘해보자!
다음 사이트에서 NASA에서 엘니뇨, 라니냐와 관련된 사진을 찾아볼 수 있다.
El Niño - NASA Science
Want to understand how interconnected our planet is—how patterns and events in one place can affect life half a world away? Study El Niño.
science.nasa.gov
해수면 높이 편차, 클로로필 농도, 표면 바람(풍향, 풍속), 구름의 양 등에 대한 데이터를 얻을 수 있으면 위 사이트에서처럼 엘니뇨, 라니냐와 관련된 다른 시각화 자료로 표현할 수 있을 것이다.




'지구과학도의 몸부림 > 수업' 카테고리의 다른 글
| [지구과학 Python] 행성 간 탐사(호먼궤도) (0) | 2025.09.11 |
|---|---|
| [지구과학 Python] 엘니뇨 라니냐 -① 엘니뇨, 라니냐 시기 시각화 (1) | 2025.06.13 |
| [천문학] 균시차 곡선 뿌시기 (0) | 2024.03.25 |
| [지구과학수행평가 참고 사이트] 미국해양대기청(NOAA) 데이터 시각화 (0) | 2024.03.25 |
| 지구 외적 기후변화 요인 (Feat. 지구과학 시뮬레이션 웹 사이트 소개 (Science Pickle)) (0) | 2023.06.17 |