[python, html/css] 안개 속보 화면 만들기: 3. 시정 자료로 그림 그리기

2024. 12. 5. 10:13·대기과학/프로그래밍

 

- 개요

저번 포스트에서 자료를 다 처리했으니 시정거리 자료로 그림을 그릴 차례입니다.

최대한 안개 경보 화면의 그림과 똑같이 그려보죠.

 

- 그림 그리기

안개 경보 화면 그림을 보며 어떻게 그릴지 생각해봅시다.

위도, 경도로 위치를 잡고 시정거리에 따라 다른 색으로 scatter plot을 그리면 되겠네요.

칼라바의 색을 따오고, 칼라바 위치를 조정해야 합니다.

 

지금 보니 시정 자료뿐만 아니라 한글을 쓰기 위한 font 설정, 도 경계를 그리기 위한 shp파일도 필요하네요.

한글 폰트를 넣는 방법은 이 글을 보시고, 한국 행정구역 shp 파일에 대한 것은 이 글을 보시면 됩니다.

 

먼저 안개 경보 그림의 칼라바 rgb값은 제가 다 땃으니 아래의 값을 쓰세요.

import matplotlib.colors as mcolors
colors = [
    (0.2, 0.2, 0.2),
    (1, 0, 1),
    (0.752941176, 0, 0),
    (0.835294118, 0, 0),
    (0.933333333, 0.043137255, 0.043137255),
    (0.964705882, 0.243137255, 0.243137255),
    (0.980392157, 0.521568627, 0.521568627),
    (0.8, 0.666666667, 0),
    (0.878431373, 0.725490196, 0),
    (0.976470588, 0.803921569, 0),
    (1, 0.862745098, 0.121568627),
    (1, 0.921568627, 0.435294118),
    (0, 0.505882353, 0),
    (0, 0.643137255, 0),
    (0, 0.835294118, 0),
    (0.117647059, 0.952941176, 0.117647059),
    (0.411764706, 0.988235294, 0.411764706),
    (0, 0.552941176, 0.870588235),
    (0, 0.670588235, 1),
    (0.243137255, 0.756862745, 1),
    (0.529411765, 0.850980392, 1),
    (0.674509804, 0.898039216, 1),
    (0.996078431, 0.996078431, 0.996078431)
]
custom_cmap = mcolors.ListedColormap(colors, name='custom_cmap')

 

이제 그림을 그릴 차례입니다.

하나하나 자세히 설명하긴 어려우니 코드에 간단한 설명만 적습니다.

 

gdf.plot(ax=ax)와 같은 식으로 gdf에서 ax에 경계를 바로 그리라고 할 수는 있지만

이상하게 그렇게 그리면 ax_position 값이 실제 ax 크기와 달라지는듯합니다.

그래서 cartopy.feature의 ShapelyFeature로 도 경계를 그립니다.

import geopandas as gpd
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
from cartopy.feature import ShapelyFeature
from matplotlib.colors import BoundaryNorm
import matplotlib.font_manager as fm

fn_font = 'NanumGothic.ttf' # 나눔고딕 폰트 사용
shp_file = "../data/shp/ctprvn_20230729/ctprvn.shp"

gdf = gpd.read_file(shp_file)
gdf = gdf.set_crs(epsg=5179)
gdf = gdf.to_crs(epsg=4326)


fig = plt.figure(figsize=(5, 7))
ax = fig.add_subplot(projection=ccrs.PlateCarree())

rgb_gray = (0.94, 0.94, 0.94) # 그림 배경색
ax.set_facecolor(rgb_gray)

ax.set_extent([124.3, 132, 32.4, 39.], crs=ccrs.PlateCarree())  # 한반도 범위 설정
ax.coastlines() 

shape_feature = ShapelyFeature(gdf.geometry, ccrs.PlateCarree(), edgecolor='black', facecolor=rgb_gray)
ax.add_feature(shape_feature, linewidth=0.5)
levels = [-999, 0, 0.1, 0.2, 0.4, 0.6, 0.8, 1.0, 1.5, 2.0, 2.5, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 10, 12, 14, 16, 18, 20, 999]
norm = BoundaryNorm(boundaries=levels, ncolors=len(colors))

sc = ax.scatter( df_vis["LON."].astype(float), df_vis["LAT."].astype(float), c=df_vis['VIS1'].astype(float)/1000, s=40, 
                edgecolor="black", zorder=10, linewidths=0.5, cmap=custom_cmap, norm=norm)
cbar = fig.colorbar(sc, ax=ax, orientation='vertical')

cbar.set_ticks(levels)
ticklabels = [f'{level:.1f}' if level <= 8 else f'{int(level)}'for level in levels]
ticklabels[0], ticklabels[-1] = "", ""
cbar.set_ticklabels(ticklabels)
cbar.ax.tick_params(size=0)

ax_position = ax.get_position() # ax로 그린 그림의 좌표값을 가져옴
"""
ax_position에서 x0, x1, y1, y2, height를 사용
ax를 x축, y축 위에 있는 하나의 사각형이라고 봤을 때 x0는 x의 최솟값, x1은 x의 최댓값
y0는 y의 최솟값, y1은 최댓값
height는 높이 (y1와 y0의 차이)
"""
cbar.ax.set_position([ax_position.x1, ax_position.y0, 0.03, ax_position.height])  # cbar의 위치와 크기 조정

cbar.ax.tick_params(labelsize=9)
fontprop = fm.FontProperties(fname=fn_font, size=12)

ax.text(ax_position.x0+0.015, ax_position.y1+0.015, '지상(1분)', font_properties= fontprop, transform=ax.figure.transFigure, color="blue", va="center")
ax.text((ax_position.x0 + ax_position.x1) * 0.5, ax_position.y1+0.015, '2024.12.02.00:00', fontsize=10, transform=ax.figure.transFigure, va="center")
ax.text(ax_position.x1, ax_position.y1, "km", fontsize=10, va="bottom", transform=ax.figure.transFigure)
plt.savefig("vis.png", bbox_inches='tight') # html/css 파일에서 png 파일로 load할 계획

 

 

안개 경보 화면 그림과 이번 포스트에서 그린 그림

 

이 정도면 안개 경보 화면에 쓸 그림으로 손색이 없어보입니다.

여기서 projection과 글씨체 등등 디테일한 부분을 좀 더 손 보면 거의 똑같이 그릴 수 있을 것 같네요.

 

다음 포스트에서는 지금까지 구한 값과 그림을 이용해서 html/css로 안개 경보 화면을 만들어보겠습니다.

'대기과학 > 프로그래밍' 카테고리의 다른 글

[python] 스마트서울 도시데이터 센서(S-DoT)로 보는 집중호우 발생시 온도장: 1. 자료 전처리  (0) 2025.01.07
[python, html/css] 안개 속보 화면 만들기: 4. html 파일 만들기  (1) 2024.12.09
[python, html/css] 안개 속보 화면 만들기: 2. 자료 다운로드와 처리  (3) 2024.12.04
[python, html/css] 안개 속보 화면 만들기: 1. 흐름 및 계획  (0) 2024.12.03
[python] 북극 진동 (Arctic Oscillation) 패턴 계산 & 그리기 4: 북극 진동 패턴 예쁘게 그리기  (1) 2024.11.20
'대기과학/프로그래밍' 카테고리의 다른 글
  • [python] 스마트서울 도시데이터 센서(S-DoT)로 보는 집중호우 발생시 온도장: 1. 자료 전처리
  • [python, html/css] 안개 속보 화면 만들기: 4. html 파일 만들기
  • [python, html/css] 안개 속보 화면 만들기: 2. 자료 다운로드와 처리
  • [python, html/css] 안개 속보 화면 만들기: 1. 흐름 및 계획
레까
레까
  • 레까
    데이터 조아
    레까
  • 전체
    오늘
    어제
    • 전체 (86)
      • 대기과학 (45)
        • 프로그래밍 (42)
        • 개념 (2)
        • 칼럼 (1)
      • 여러가지 데이터 (5)
        • 프로그래밍 & 분석 (5)
      • 프로그래밍 (15)
        • 파이썬 (8)
        • 시각화 (6)
        • 유용 (1)
      • 프로젝트 (17)
        • 기계학습 기반 서울 기온 예측 (9)
        • 사과게임 매크로 만들기 (4)
        • 버스 한 번으로 특정 지역에 갈 수 있는 지역 찾.. (4)
      • 데이터리안 SQL 공부 (3)
      • 주제별 링크 모음 (1)
      • 백업 (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
레까
[python, html/css] 안개 속보 화면 만들기: 3. 시정 자료로 그림 그리기
상단으로

티스토리툴바