You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
First thank you so much for your work. While using Ultraplot, I notice that the syntax leftlabels_kw = {'size': xx} doesn't have any effect on changing the fontsize of the leftlabels. Could you take a quick look on that?
Here given my code. I don't think that my configuration or my code has any other updates/moderation compared to you.
I attached my code and link to my data if you want to try it.
DataLink: https://drive.google.com/drive/folders/1p7vNZMVFiFJQAwR4NClucdH48eJQLgPo?usp=sharing
`def doubling(resample_mode, ind='Tx', gev_fit=False, doubling: Optional[Literal['linear', 'log', 'both']] = 'linear'):
data_dict = {}
with h5py.File(f'OG_{resample_mode}.h5', 'r') as f:
for key,item in f.items():
data_dict[key] = item[:]
if os.path.exists(f"OG_{resample_mode}.csv"):
data_fitted_df = pd.read_csv(f"OG_{resample_mode}.csv")
if resample_mode == 0:
data_fitted_df.rename(columns = {'Unnamed: 0': 'name_station'}, inplace=True)
else:
data_fitted_df.rename(columns = {'station': 'name_station'}, inplace=True)
else:
data_fitted_df = fit_gev(ind, og=True, resample_mode=0)
num_station = len(data_fitted_df.index)
ri = RI(resample_mode = resample_mode, monthly = False)
TR = 50
mu_T_threshold = 3 # Threshold for fit of sigma 2x
# Initialize the variables
mu_T = np.linspace(0,10,100) #local temperature rise
TR_rise = np.zeros(shape=(mu_T.size, num_station)) # return period
E_rise = np.zeros(shape=(mu_T.size, num_station)) # exceedence probability
ODD_rise = np.zeros(shape=(mu_T.size, num_station)) # odd of exceeding
sigma_2x = np.zeros(mu_T.size) # slope of the line
sigma_2x_fit = np.zeros(mu_T.size) # slope of the line
fig, axes = uplt.subplots(ncols = 2, nrows = 2, sharey = False)
axes.format(
abc="a.",
abcloc="l",
grid=False,
# toplabels=("Column 1", "Column 2"),
leftlabels=("Empirical", " GEV"),
leftlabels_kw = {'size': '60'}
)
ix = axes[0].inset(
[1, 2000, 2, 5000],
transform="data",
zoom=True,
zoom_kw={"ec": "blush", "ls": "--", "lw": 2},
yscale = 'log', yscale_kw = {'base': 2})
ix.format(xlim=(0, 3), ylim=(0, 512), xlocator = np.arange(0,4,1), fontsize = 7, color="red8", linewidth=1)
#! Use the daily data to calculate the exceedence probability
for i,name_station in enumerate(data_dict.keys()):
# Get input values
station_df = data_fitted_df[data_fitted_df['name_station'] == name_station]
data = data_dict[name_station]
mu_org = station_df['loc'].values[0]
sigma_org = station_df['scale'].values[0]
k_org = station_df['shape'].values[0]
clus = station_df['cluster'].values[0]
x0_GEV = x_Tr(TR, mu_org, sigma_org, k_org, ri) # Reverse of cdf at TR
E_base = ri/TR
if not gev_fit:
# ALL DATA
if resample_mode == 0:
# Value of x that has return period: 50 years (x_50)
# Calculate the exceedence probability emperically
# Find the exceedance value of all values
E_list = EV(data, mu_org, sigma_org, k_org) # TODO: Think about the exceedance of ri = 1/3 or just all data
# Find the last index of each exceedance value
# Find the corresponding real value of the exceedance value
last_index_E = last_index(E_list)
x_tmp, E_tmp = data[last_index_E], E_list[last_index_E]
# Develop the relationship between x and E
# Use x_50 to find E_50 (exceedence probability of x_50)(percent)
E_base = f_interp(x0_GEV,x_tmp,E_tmp) # or E0 if you want original use linear but it's kinda outdated
# Rising odd
# E(x_50 - mu_T) - right shift compared to original
for j, mu in enumerate(mu_T):
x_rise = x_tmp + mu
E_rise[j,i] = f_interp(x0_GEV, x_rise, E_tmp) # Eceedance of rise
# EXTREME DATA (n events/year)
else:
#?? Why doesn't they use the same way?
#! They define Exceedence first here??? Why???
x_tmp = data[last_index(data)][::-1] # Descending
len_x = x_tmp.size
E_tmp = np.linspace(1/len_x,len_x/(len_x+1),len_x)
#? x_temp is descending <= we try to match the CDF => larger temp = smaller exceedance
x0_emp = f_interp(E_base, E_tmp, x_tmp)
for j, mu in enumerate(mu_T):
x_rise = x_tmp + mu
E_rise[j,i] = f_interp(x0_emp, x_rise, E_tmp)
TR_rise[j,i] = ri/E_rise[j,i]
# Use GEV distribution to calculate the exceedence probability
else:
#? Use GEV distribution to calculate the exceedence probability
for j, mu in enumerate(mu_T):
x_rise = x0_GEV + mu
E_rise[j,i] = EV(x0_GEV, mu_org+mu, sigma_org, k_org)
TR_rise[j,i] = ri/E_rise[j,i]
ODD_rise[:,i] = E_rise[:,i]/(1-E_rise[:,i])
ODD_base = E_base/(1-E_base)
ODD_ratio = ODD_rise[:,i]/ODD_base
# ODD_ratio_log = np.log2(ODD_ratio)
ODD_ratio_log = np.log(np.log(ODD_ratio))
if ODD_base in (np.nan, 0):
sigma_2x[i] = np.nan
sigma_2x_fit[i] = np.nan
else:
# Index for mu_T < mu_T_threshold
index_sel = np.where(mu_T<mu_T_threshold)
x_sel = mu_T[index_sel]
# Choose ODD_ratio_log where mu_t < mu_T_threshold
ODD_ratio_log_sel = ODD_ratio_log[index_sel]
log_index = ~np.isnan(ODD_ratio_log_sel) # index of non-NaN values
#? Explaination
#? Slope of the line = doubling rate of growth
#? We find the slope of this line (m): log_2(ODD_ratio) = mu_T/sigma_2x = m.mu_T
#? => sigma_2x = 1/m
# Method 1: Linear
if doubling in ('linear', 'both'):
sigma_2x[i] = 1/np.nanmean(np.diff(ODD_ratio_log_sel)/np.diff(x_sel))
# Method 2: Polynomial
if doubling in ('log', 'both'):
p = np.polyfit(x_sel[log_index], ODD_ratio_log_sel[log_index], 1)
sigma_2x[i] = 1/p[0] # Use polynomial relationship
axes[0].plot(mu_T, ODD_ratio, color='blue9', alpha=0.4, linewidth = 1)
ix.plot(mu_T, ODD_ratio, color='blue9', alpha=0.4, linewidth = 1)
axes[1].plot(mu_T/sigma_2x[i], ODD_ratio_log, color='blue9', alpha=0.5, linewidth = 1)
axes[0].format(xlim = (0,8), ylim = (0,8000), xlabel = r'$\mu_T$', ylabel = r'$\frac{\mathrm{Odds}}{\mathrm{Odds_0}}$')
# if resample_mode==0: ax.plot(np.linspace(0,40,1000), 2.5*(np.log2(np.linspace(0,40,1000)+1)), color='gray', linestyle='-.', linewidth=10)
axes[1].plot(mu_T,mu_T, color = 'r', linestyle = '--')
# Draw lines at x=0 and y=0
axes[1].format(xlabel = r'$\frac{\mu_T}{\tilde{\sigma}}$',
ylabel = r'$\log\log\left(\frac{\mathrm{Odds}}{\mathrm{Odds_0}}\right)$',
ylim = (0,4),xlim = (0,4),ylocator = (np.arange(0,5,1)), xlocator = (np.arange(0, 18, 2)))
# The equation of odds of exceedance
axes[1].text(2, 0.75, r'$\log\log\left(\frac{\mathrm{Odds}}{\mathrm{Odds}_0}\right) = \frac{\mu_T}{\tilde{\sigma}}$',
fontsize = 10, fontweight = 'bold',
bbox=dict(boxstyle="round",
alpha = 0.8,
ec=(1., 0.5, 0.5),
fc=(0.9,0.9,0.9),
))
axes[1].annotate("",xy=(0.55, 0.28), xycoords = 'axes fraction', xytext = (0.45, 0.4),
textcoords = 'axes fraction', arrowprops = {'arrowstyle':'simple, head_width=0.5, head_length=1', 'facecolor': 'black','linewidth': 0.25, 'connectionstyle':"arc3,rad=-0.2"})
fig.savefig(os.getenv('img')+f"/GEV/Doubling_rate_{resample_mode}_{"gev" if gev_fit else "emp"}.png")
Activity
cvanelteren commentedon Jan 19, 2026
Any particular code you have issues with? This seems to work fine for me
UltraPlot: 1.71.0
Matplotlib: 3.10.8
Python: 3.14.2
tamnnm commentedon Jan 20, 2026
Here given my code. I don't think that my configuration or my code has any other updates/moderation compared to you.
I attached my code and link to my data if you want to try it.
DataLink: https://drive.google.com/drive/folders/1p7vNZMVFiFJQAwR4NClucdH48eJQLgPo?usp=sharing
`def doubling(resample_mode, ind='Tx', gev_fit=False, doubling: Optional[Literal['linear', 'log', 'both']] = 'linear'):
data_dict = {}
with h5py.File(f'OG_{resample_mode}.h5', 'r') as f:
for key,item in f.items():
data_dict[key] = item[:]
if os.path.exists(f"OG_{resample_mode}.csv"):
data_fitted_df = pd.read_csv(f"OG_{resample_mode}.csv")
if resample_mode == 0:
data_fitted_df.rename(columns = {'Unnamed: 0': 'name_station'}, inplace=True)
else:
data_fitted_df.rename(columns = {'station': 'name_station'}, inplace=True)
else:
data_fitted_df = fit_gev(ind, og=True, resample_mode=0)
`
cvanelteren commentedon Jan 20, 2026
Could you please provide a minimal and verifiable example?
cvanelteren commentedon Jan 20, 2026
I see the issue. Fix incoming
[-]Update leftlabels has no effect[/-][+]Inset axis formats parent axis[/+]