Skip to content

Commit f99d5e3

Browse files
committed
new option: use arrow to contrast two highlighted models
1 parent e133c6c commit f99d5e3

File tree

1 file changed

+60
-25
lines changed

1 file changed

+60
-25
lines changed

pcmdi_metrics/graphics/parallel_coordinate_plot/parallel_coordinate_plot_lib.py

Lines changed: 60 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,11 @@ def parallel_coordinate_plot(
1515
metric_names,
1616
model_names,
1717
models_to_highlight=list(),
18+
models_to_highlight_by_line=True,
1819
models_to_highlight_colors=None,
1920
models_to_highlight_labels=None,
21+
models_to_highlight_markers=['s', 'o', '^', '*'],
22+
models_to_highlight_markers_size=10,
2023
fig=None,
2124
ax=None,
2225
figsize=(15, 5),
@@ -37,7 +40,10 @@ def parallel_coordinate_plot(
3740
group2_name="group2",
3841
comparing_models=None,
3942
fill_between_lines=False,
40-
fill_between_lines_colors=("green", "red"),
43+
fill_between_lines_colors=("red", "green"),
44+
arrow_between_lines=False,
45+
arrow_between_lines_colors=("red", "green"),
46+
arrow_alpha=1,
4147
vertical_center=None,
4248
vertical_center_line=False,
4349
vertical_center_line_label=None,
@@ -50,9 +56,12 @@ def parallel_coordinate_plot(
5056
- `data`: 2-d numpy array for metrics
5157
- `metric_names`: list, names of metrics for individual vertical axes (axis=1)
5258
- `model_names`: list, name of models for markers/lines (axis=0)
53-
- `models_to_highlight`: list, default=None, List of models to highlight as lines
59+
- `models_to_highlight`: list, default=None, List of models to highlight as lines or marker
60+
- `models_to_highlight_by_line`: bool, default=True, highlight as lines. If False, as marker
5461
- `models_to_highlight_colors`: list, default=None, List of colors for models to highlight as lines
5562
- `models_to_highlight_labels`: list, default=None, List of string labels for models to highlight as lines
63+
- `models_to_highlight_markers`: list, matplotlib markers for models to highlight if as marker
64+
- `models_to_highlight_markers_size`: float, size of matplotlib markers for models to highlight if as marker
5665
- `fig`: `matplotlib.figure` instance to which the parallel coordinate plot is plotted.
5766
If not provided, use current axes or create a new one. Optional.
5867
- `ax`: `matplotlib.axes.Axes` instance to which the parallel coordinate plot is plotted.
@@ -76,7 +85,10 @@ def parallel_coordinate_plot(
7685
- `group2_name`: string, needed for violin plot legend if splited to two groups, for the 2nd group. Default is 'group2'.
7786
- `comparing_models`: tuple or list containing two strings for models to compare with colors filled between the two lines.
7887
- `fill_between_lines`: bool, default=False, fill color between lines for models in comparing_models
79-
- `fill_between_lines_colors`: tuple or list containing two strings for colors filled between the two lines. Default=('green', 'red')
88+
- `fill_between_lines_colors`: tuple or list containing two strings of colors for filled between the two lines. Default=('red', 'green')
89+
- `arrow_between_lines`: bool, default=False, place arrows between two lines for models in comparing_models
90+
- `arrow_between_lines_colors`: tuple or list containing two strings of colors for arrow between the two lines. Default=('red', 'green')
91+
- `arrow_alpha`: float, default=1, transparency of arrow (faction between 0 to 1)
8092
- `vertical_center`: string ("median", "mean")/float/integer, default=None, adjust range of vertical axis to set center of vertical axis as median, mean, or given number
8193
- `vertical_center_line`: bool, default=False, show median as line
8294
- `vertical_center_line_label`: str, default=None, label in legend for the horizontal vertical center line. If not given, it will be automatically assigned. It can be turned off by "off"
@@ -230,8 +242,14 @@ def parallel_coordinate_plot(
230242
label = models_to_highlight_labels[mh_index]
231243
else:
232244
label = model
233-
234-
ax.plot(range(N), zs[j, :], "-", c=color, label=label, lw=3)
245+
246+
if models_to_highlight_by_line:
247+
ax.plot(range(N), zs[j, :], "-", c=color, label=label, lw=3)
248+
else:
249+
ax.plot(range(N), zs[j, :], models_to_highlight_markers[mh_index],
250+
c=color, label=label,
251+
markersize=models_to_highlight_markers_size)
252+
235253
mh_index += 1
236254
else:
237255
if identify_all_models:
@@ -251,8 +269,8 @@ def parallel_coordinate_plot(
251269
vertical_center_line_label = None
252270
ax.plot(range(N), zs_middle, "-", c="k", label=vertical_center_line_label, lw=1)
253271

254-
# Fill between lines
255-
if fill_between_lines and (comparing_models is not None):
272+
# Compare two models
273+
if comparing_models is not None:
256274
if isinstance(comparing_models, tuple) or (
257275
isinstance(comparing_models, list) and len(comparing_models) == 2
258276
):
@@ -261,24 +279,41 @@ def parallel_coordinate_plot(
261279
m2 = model_names.index(comparing_models[1])
262280
y1 = zs[m1, :]
263281
y2 = zs[m2, :]
264-
ax.fill_between(
265-
x,
266-
y1,
267-
y2,
268-
where=y2 >= y1,
269-
facecolor=fill_between_lines_colors[0],
270-
interpolate=True,
271-
alpha=0.5,
272-
)
273-
ax.fill_between(
274-
x,
275-
y1,
276-
y2,
277-
where=y2 <= y1,
278-
facecolor=fill_between_lines_colors[1],
279-
interpolate=True,
280-
alpha=0.5,
281-
)
282+
283+
# Fill between lines
284+
if fill_between_lines:
285+
ax.fill_between(
286+
x,
287+
y1,
288+
y2,
289+
where=(y2 > y1),
290+
facecolor=fill_between_lines_colors[0],
291+
interpolate=False,
292+
alpha=0.5,
293+
)
294+
ax.fill_between(
295+
x,
296+
y1,
297+
y2,
298+
where=(y2 < y1),
299+
facecolor=fill_between_lines_colors[1],
300+
interpolate=False,
301+
alpha=0.5,
302+
)
303+
304+
if arrow_between_lines:
305+
# Add vertical arrows
306+
for xi, yi1, yi2 in zip(x, y1, y2):
307+
if (yi2 > yi1):
308+
arrow_color = arrow_between_lines_colors[0]
309+
elif (yi2 < yi1):
310+
arrow_color = arrow_between_lines_colors[1]
311+
else:
312+
arrow_color = None
313+
arrow_length = yi2 - yi1
314+
ax.arrow(xi, yi1, 0, arrow_length, color=arrow_color,
315+
length_includes_head=True,
316+
alpha=arrow_alpha, width=0.05, head_width=0.15)
282317

283318
ax.set_xlim(-0.5, N - 0.5)
284319
ax.set_xticks(range(N))

0 commit comments

Comments
 (0)