Skip to content

Commit

Permalink
changed visualization for error contribution of high flows and low fl…
Browse files Browse the repository at this point in the history
…ows to pies.
  • Loading branch information
schwemro committed Mar 5, 2021
1 parent 69b4225 commit d63dfc4
Show file tree
Hide file tree
Showing 6 changed files with 241 additions and 184 deletions.
315 changes: 170 additions & 145 deletions de/de.py

Large diffs are not rendered by default.

25 changes: 25 additions & 0 deletions de/fdc.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,31 @@
_sim_lab = "Simulated"


def calc_fdc(ts, prob):
"""
Calculate numeric values of the flow duration curve for a single
hydrologic time series.
Parameters
----------
ts : (N,)array_like
hydrologic time series
prob : (N,)array_like
Quantile or sequence of quantiles to compute.
Returns
----------
fdc_vals : (N,)array_like
numeric values to plot flow duration curve
"""
data = ts[np.logical_not(np.isnan(ts))]
data = np.sort(data) # sort values by ascending order
fdc_vals = np.quantile(data, prob)[::-1]

return fdc_vals


def fdc(ts):
"""
Flow duration curve for a single hydrologic time series.
Expand Down
83 changes: 45 additions & 38 deletions de/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -216,8 +216,10 @@ def fdc_obs_sim_ax(obs, sim, ax, fig_num): # pragma: no cover
----------
obs : series
observed time series
sim : series
simulated time series
ax : axes
Axes object to draw the plot onto
fig_num : string
Expand Down Expand Up @@ -252,10 +254,13 @@ def plot_obs_sim_ax(obs, sim, ax, fig_num): # pragma: no cover
----------
obs : series
observed time series
sim : series
simulated time series
ax : axes
Axes object to draw the plot onto
fig_num : string
string object for figure caption
"""
Expand Down Expand Up @@ -355,7 +360,6 @@ def diag_polar_plot_multi_fc(
# determine axis limits
yy = np.arange(0.01, ax_lim, delta)
c_levels = np.arange(0, ax_lim, 0.2)
off_max = 0.14 * ax_lim

len_yy = 360
# len_yy1 = 90
Expand Down Expand Up @@ -424,34 +428,28 @@ def diag_polar_plot_multi_fc(
elif btot == 0:
exp_err = 0

# scale marker size
s_max = 72
s_hf = s_max * abs(errhf)
s_lf = s_max * abs(errlf)

# marker offset
if bd != 0:
phi_off = np.arccos(1 - (off_max**2/(2*eff**2)))/2
if (ang > 0) & (ang <= np.pi/2):
phi_hf = ang + phi_off * abs(errhf)
phi_lf = ang - phi_off * abs(errlf)
elif (ang > np.pi/2) & (ang <= np.pi):
phi_hf = ang - phi_off * abs(errhf)
phi_lf = ang + phi_off * abs(errlf)
elif (ang >= -np.pi) & (ang < -np.pi/2):
phi_hf = ang - phi_off * abs(errhf)
phi_lf = ang + phi_off * abs(errlf)
elif (ang >= -np.pi/2) & (ang <= 0):
phi_hf = ang + phi_off * abs(errhf)
phi_lf = ang - phi_off * abs(errlf)
# calculate pies to display error contribution of high flows and low
# flows
# calculate the points of the first pie marker
# these are just the origin (0, 0) + some (cos, sin) points on a circle
r1 = abs(errhf)/2
x1 = np.cos(2 * np.pi * np.linspace(0.25 - r1/2, 0.25 + r1/2))
y1 = np.sin(2 * np.pi * np.linspace(0.25 - r1/2, 0.25 + r1/2))
xy1 = np.row_stack([[0, 0], np.column_stack([x1, y1])])
s1 = np.abs(xy1).max()

r2 = abs(errlf)/2
x2 = np.cos(2 * np.pi * np.linspace(0.75 - r2/2, 0.75 + r2/2))
y2 = np.sin(2 * np.pi * np.linspace(0.75 - r2/2, 0.75 + r2/2))
xy2 = np.row_stack([[0, 0], np.column_stack([x2, y2])])
s2 = np.abs(xy2).max()

# diagnose the error
if abs(bm) <= l and exp_err > l and eff > eff_l:
c = ax.scatter(ang, eff, color=rgba_color, zorder=3)
d = ax.scatter(ang, eff, color="grey", marker=".", zorder=4)
if bd != 0:
c0 = ax.scatter(phi_hf, eff, color=rgba_color, zorder=5, marker="^", s=s_hf)
c1 = ax.scatter(phi_lf, eff, color=rgba_color, zorder=5, marker="v", s=s_lf)
c0 = ax.scatter(ang, eff, marker=xy1, s=s1**2 * 200, facecolor=rgba_color, zorder=3)
c1 = ax.scatter(ang, eff, marker=xy2, s=s2**2 * 200, facecolor=rgba_color, zorder=3)
c = ax.scatter(ang, eff, s=36, facecolor=rgba_color, zorder=3)
c2 = ax.scatter(ang, eff, s=4, facecolor='grey', zorder=3)
ax.annotate(
txt,
xy=(ang, eff),
Expand All @@ -463,11 +461,10 @@ def diag_polar_plot_multi_fc(
va="center",
)
elif abs(bm) > l and exp_err <= l and eff > eff_l:
c = ax.scatter(ang, eff, color=rgba_color, zorder=3)
d = ax.scatter(ang, eff, color="grey", marker=".", zorder=4)
if bd != 0:
c0 = ax.scatter(phi_hf, eff, color=rgba_color, zorder=5, marker="^", s=s_hf)
c1 = ax.scatter(phi_lf, eff, color=rgba_color, zorder=5, marker="v", s=s_lf)
c0 = ax.scatter(ang, eff, marker=xy1, s=s1**2 * 200, facecolor=rgba_color, zorder=3)
c1 = ax.scatter(ang, eff, marker=xy2, s=s2**2 * 200, facecolor=rgba_color, zorder=3)
c = ax.scatter(ang, eff, s=36, facecolor=rgba_color, zorder=3)
c2 = ax.scatter(ang, eff, s=4, facecolor='grey', zorder=3)
ax.annotate(
txt,
xy=(ang, eff),
Expand All @@ -479,11 +476,10 @@ def diag_polar_plot_multi_fc(
va="center",
)
elif abs(bm) > l and exp_err > l and eff > eff_l:
c = ax.scatter(ang, eff, color=rgba_color, zorder=3)
d = ax.scatter(ang, eff, color="grey", marker=".", zorder=4)
if bd != 0:
c0 = ax.scatter(phi_hf, eff, color=rgba_color, zorder=5, marker="^", s=s_hf)
c1 = ax.scatter(phi_lf, eff, color=rgba_color, zorder=5, marker="v", s=s_lf)
c0 = ax.scatter(ang, eff, marker=xy1, s=s1**2 * 200, facecolor=rgba_color, zorder=3)
c1 = ax.scatter(ang, eff, marker=xy2, s=s2**2 * 200, facecolor=rgba_color, zorder=3)
c = ax.scatter(ang, eff, s=36, facecolor=rgba_color, zorder=3)
c2 = ax.scatter(ang, eff, s=4, facecolor='grey', zorder=3)
ax.annotate(
txt,
xy=(ang, eff),
Expand Down Expand Up @@ -537,8 +533,19 @@ def diag_polar_plot_multi_fc(
)

# legend for error contribution of high flows and low flows
ax.scatter([], [], color='k', zorder=2, marker="^", s=36, label=r'high flows ($\epsilon_{hf}=0.5$)')
ax.scatter([], [], color='k', zorder=2, marker="v", s=36, label=r'low flows ($\epsilon_{lf}=0.5$)')
rl1 = 1/2
xl1 = np.cos(2 * np.pi * np.linspace(0.25 - rl1/2, 0.25 + rl1/2))
yl1 = np.sin(2 * np.pi * np.linspace(0.25 - rl1/2, 0.25 + rl1/2))
xyl1 = np.row_stack([[0, 0], np.column_stack([xl1, yl1])])
sl1 = np.abs(xyl1).max()

rl2 = 1/2
xl2 = np.cos(2 * np.pi * np.linspace(0.75 - rl2/2, 0.75 + rl2/2))
yl2 = np.sin(2 * np.pi * np.linspace(0.75 - rl2/2, 0.75 + rl2/2))
xyl2 = np.row_stack([[0, 0], np.column_stack([xl2, yl2])])
sl2 = np.abs(xyl2).max()
ax.scatter([], [], color='k', zorder=2, marker=xyl1, s=sl1**2 * 200, label=r'high flows ($\epsilon_{hf}=1$)')
ax.scatter([], [], color='k', zorder=2, marker=xyl2, s=sl2**2 * 200, label=r'low flows ($\epsilon_{lf}=1$)')
ax.legend(loc='upper right', title="Error contribution of", fancybox=False,
frameon=False, bbox_to_anchor=(1.3, 1.1), title_fontsize=11,
fontsize=11, handletextpad=0.1)
Expand Down
2 changes: 1 addition & 1 deletion paper_code.py
Original file line number Diff line number Diff line change
Expand Up @@ -1752,4 +1752,4 @@
PATH_FIG, "kge_diag_real_case.pdf"
))
fig_kge.savefig(path_pdf, dpi=250)

Binary file modified tests/images/de/multi/test_multi_diag_polar_plot.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified tests/images/de/single/test_single_diag_polar_plot.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit d63dfc4

Please sign in to comment.