[Python] Python Matplotlib : How to fix axes size regardness of cbar or extent

Discussão em 'Python' iniciado por Stack, Julho 1, 2025.

  1. Stack

    Stack Membro Participativo

    I'm using matplotlib library for visualizing atmospheric figure. I want to fix my axes size, but it doesn't work well. For example, everything is same but only cbar orientation(horizontal -> vertical) changes, axes size became diffrent. Moreover, I want to change ax.extent range but same axes size. For example, I did 2 options

    1. axis = [126.1,127.4,34.77,35.9]
    2. axis = [125,127.7,33.8,36.2] ax.set_extent(axis,ccrs.PlateCarree()) In this case, 2 axis size is different. I want to fix all of my figures' sizes

    Here's my entire code I marked bolde for plotting and figure code (https://i.sstatic.net/twlPsRyf.png) (https://i.sstatic.net/JG0FwR2C.png) these two images code are not correctly same, but figsize is same (10,10) two images extent range are different, so axes size is different.

    from netCDF4 import Dataset
    import matplotlib.pyplot as plt
    import cartopy.crs as ccrs
    import numpy as np
    from wrf import (ll_to_xy, to_np, getvar, get_cartopy, extract_times, ALL_TIMES, latlon_coords)
    from cartopy.feature import NaturalEarthFeature
    from cartopy.io.shapereader import Reader
    from cartopy.feature import ShapelyFeature
    import cmaps
    import pytz
    from datetime import datetime
    import matplotlib
    import time
    import os
    import pandas as pd
    import matplotlib.collections as mcoll
    matplotlib.use('Agg')
    start_time = time.time()

    cases = ['ndown','x10', 'x01']
    for case in cases :
    print(case)
    k = 24 #TIME DURATION

    start_date = '2021-12-17_00'
    end_date = '2021-12-18_00'
    variable = 'RAINC'
    variable2 = 'RAINNC'

    axis = [126.1,127.4,34.77,35.9]
    x_ticks = [126,126.5,127,127.5]
    y_ticks = [35,35.5,36]
    '''
    axis = [125,127.7,33.8,36.2]
    x_ticks = [125,125.5,126,126.5,127,127.5]
    y_ticks = [34,34.5,35,35.5,36]
    '''
    axis_on =True
    print(f"원하는 시간 : {start_date} ~ {end_date}")

    #컬러바 설정
    newcmp = cmaps.WhBlGrYeRe
    start = 5
    end = 25
    r = 2.5
    levels = np.arange(start,end+r,r)
    colorbar = list(np.arange(start,end+r,5))
    # 경로 설정
    shp_path = "/home/chwan/data/shp/241002/gadm41_KOR_1.shp"
    base_path1 = f"/home/chwan/wrfrun/ROUGHNESS/nesting/YSU_{case.split('_')[0]}/run/"
    #base_path1 = "/home/chwan/wrfrun/ROUGHNESS/landuse24_znt_df/run/"
    #output_dir = f"ACC_{base_path1.split('/')[-3]}_{variable}single"
    output_dir = f"ACC_{case}_{variable}single"

    os.makedirs(output_dir, exist_ok=True)

    ##코드 시작##
    kst = 'Asia/Seoul'
    sd_utc = pd.to_datetime(start_date, format='%Y-%m-%d_%H').tz_localize(kst).tz_convert('UTC')
    sd_utc = sd_utc-pd.Timedelta(hours=3)
    ed_utc = pd.to_datetime(end_date, format='%Y-%m-%d_%H').tz_localize(kst).tz_convert('UTC')
    dates = (pd.date_range(start=sd_utc, end=ed_utc, freq='H'))
    files = np.unique([f"wrfout_d01_{d.year:04d}-{d.month:02d}-{d.day:02d}_00:00:00" for d in dates])
    print(f"사용된 자료 : {files}")
    with Dataset(f"{base_path1}{files[0]}") as ncfile:
    first_times = pd.to_datetime(getvar(ncfile, 'times', timeidx=ALL_TIMES).values).tz_localize('UTC')

    with Dataset(f"{base_path1}{files[-1]}") as ncfile:
    end_times = pd.to_datetime(getvar(ncfile, 'times', timeidx=ALL_TIMES).values).tz_localize('UTC')
    start_idx = (first_times == sd_utc).argmax()
    end_idx = (end_times == ed_utc).argmax()
    print(f"Start index: {start_idx}, End index: {end_idx}")
    d = 0
    for data in files:
    filename1 = f"{base_path1}{data}"
    ncfile1 = Dataset(filename1, "r")
    T1 = getvar(ncfile1, f"{variable}", timeidx = ALL_TIMES) + getvar(ncfile1, f"{variable2}", timeidx = ALL_TIMES)
    times = extract_times(ncfile1, timeidx=ALL_TIMES)
    if len(files) !=1 :
    if int(data.split("_")[-2].split("-")[-1]) == dates[0].day :
    T1 = T1[start_idx:]
    times = times[start_idx:]
    elif int(data.split("_")[-2].split("-")[-1]) == dates[-1].day :
    T1 = T1[:end_idx+1]
    times = times[:end_idx+1]
    else :
    T1 = T1[start_idx:end_idx+1]
    times = times[start_idx:end_idx+1]
    print(times)
    ** for i, time in enumerate(times):
    print(f"{case} , 처리 중인 시간(UTC) : {time}")
    fig = plt.figure(figsize=(10,10))
    ax = fig.add_axes([0.1, 0.1, 0.8, 0.8], projection=ccrs.PlateCarree())
    shpfile = Reader(shp_path)
    shapefile_feature = ShapelyFeature(shpfile.geometries(),ccrs.PlateCarree(), edgecolor = 'black', facecolor = 'none', linewidth=1)
    ax.add_feature(shapefile_feature)
    if axis_on :
    ax.set_extent(axis,ccrs.PlateCarree())
    else :
    pass
    ax.set_xticks(x_ticks)
    ax.set_yticks(y_ticks)
    ax.tick_params(axis='both', labelsize=12)
    #ax.set_xticklabels([str(x) for x in np.arange(axis[0], axis[1] + 1, 1)], fontsize=14)
    #ax.set_yticklabels([str(y) for y in np.arange(axis[2], axis[3] + 1, 1)], fontsize=14)
    ax.set_xlabel("Longitude", fontsize=18, fontweight = 'bold',labelpad=0)
    ax.set_ylabel("Latitude", fontsize=18, fontweight = 'bold',labelpad=15)
    lats, lons = latlon_coords(T1)
    if i < k and data == files[0] :
    print("continue")
    continue
    elif i < k and data != files[0] :
    T_former = getvar(Dataset(f"{base_path1}{files[d-1]}","r",timeidx= ALL_TIMES), f"{variable}")+getvar(Dataset(f"{base_path1}{files[d-1]}","r"), f"{variable2}", timeidx = ALL_TIMES)
    T_form = T_former.isel(Time=i-k)
    times_start = T1['Time']
    times_end = T_form['Time']
    hfx_diff = T1 - T_form
    else :
    hfx_diff = T1 - T1[i-k]
    times_start = T1['Time']
    times_end = T1[i-k]['Time']
    #hfx_diff = T1 - T1[i-k]
    contourf = ax.contourf(to_np(lons), to_np(lats), hfx_diff, levels=levels,
    transform=ccrs.PlateCarree(), cmap=newcmp, vmin=start, vmax=end, extend='max')
    line2 = ax.plot([126.5,126.95],[35.975,35.375], color = 'black', linewidth=4,transform = ccrs.PlateCarree())
    #ax.plot(126.89, 35.45961, color='black', marker='o', markersize=8, transform=ccrs.PlateCarree())
    target_lon = 126.9 #정읍
    target_lat = 35.45961 #정읍세로
    #plot1 = ax.plot(126.7503, 35.5813, color = 'pink', marker='o', markersize=8, transform=ccrs.PlateCarree())
    #plot1 = ax.plot(126.6396, 35.6714, color = 'pink', marker='o', markersize=8, transform=ccrs.PlateCarree())

    #plot1 = ax.plot(126.9,35.45961, 'bo', markersize=8,transform = ccrs.PlateCarree())
    #plot1 = ax.plot(126.861017,35.491204, color = 'pink',marker='o', markersize=8,transform = ccrs.PlateCarree())
    #ax.plot(126.67, 35.5, color='black', marker='o', markersize=10, transform=ccrs.PlateCarree())
    #ax.plot(127.2, 35.45961, color='black', marker='o', markersize=10, transform=ccrs.PlateCarree())

    # 시간 처리
    # 컬러바 추가
    cbar = plt.colorbar(contourf, orientation='horizontal', shrink=0.5, pad=0.075, aspect=15)
    cbar.ax.tick_params(labelsize=11)
    cbar.set_ticks(colorbar)
    cbar.set_ticklabels(colorbar)
    cbar.set_ticklabels([f"{int(x)}" for x in colorbar])
    cbar.set_label("Accumulated Precipitation(mm)", labelpad=10, rotation=0, ha='center', va='center',fontsize=15)

    start_time_str = str(times_start.values) # '2021-12-18T15:00:00.000000000'
    end_time_str = str(times_end.values) # '2021-12-18T18:00:00.000000000'
    print(start_time_str,end_time_str)
    # datetime64에서 Python datetime으로 변환
    start_time_obj_utc = pd.Timestamp(start_time_str).to_pydatetime()
    end_time_obj_utc = pd.Timestamp(end_time_str).to_pydatetime()

    # UTC -> KST 변환
    start_time_obj_kst = pytz.utc.localize(start_time_obj_utc).astimezone(pytz.timezone(kst))
    end_time_obj_kst = pytz.utc.localize(end_time_obj_utc).astimezone(pytz.timezone(kst))
    print(start_time_obj_kst,end_time_obj_kst)
    ax.text(0.2, 1.05, f"{end_time_obj_kst.strftime('%Y-%m-%d %H:%M:%S')} ~ {start_time_obj_kst.strftime('%Y-%m-%d %H:%M:%S')}",
    transform=ax.transAxes, fontsize=12, verticalalignment='top', horizontalalignment='left')

    image_filename = f"{output_dir}/T2diff_{str(time).split('.')[0]}.png"
    plt.savefig(image_filename, dpi=300)
    plt.close()**
    print(f"{data.split('_')[-2].split('-')[-1]}일 생성 완료")
    d +=1

    Continue reading...

Compartilhe esta Página