Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update plot scripts to work with Python 3 changes; improve heatmap legibility #10

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
10 changes: 6 additions & 4 deletions metrics/scripts/averages.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import matplotlib.pyplot as plt

import argparse
from statistics import mean, harmonic_mean, median
from statistics import mean, harmonic_mean, geometric_mean, median
import math
import sys

Expand All @@ -16,7 +16,9 @@ def geomean(n):
# geometric_mean was not added to statistics until Python 3.8
if (sys.version_info.major > 3) or (
sys.version_info.major == 3 and sys.version_info.minor >= 8):
return statistics.geometric_mean(n)
if 0 in n:
return 0
return geometric_mean(n)
Comment on lines +19 to +21
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Previously this branch was being used to prevent geometric_mean from being imported with Python versions that didn't exist. I don't think this new code will work with older Python versions. That may be okay, but I'm not sure what @tomdeakin plans for compatibility here.

else:
return np.prod(n)**(1.0 / float(len(n)))

Expand Down Expand Up @@ -70,7 +72,6 @@ def pp(n):
args.input_file,
skipinitialspace=True,
sep=r',\s+',
delimiter=',',
na_values='X')

# In the case of trailing whitespace, the X don't get converted.
Expand Down Expand Up @@ -124,7 +125,8 @@ def pp(n):
for (name, f) in averages.items():
avg = data_nona.apply(f, raw=True).copy()
avg.name = name
results = results.append(avg, ignore_index=False)
results = pd.concat([results, avg], axis=1, ignore_index=False)
results = results.transpose()

# Sort columns according to their PP value
# sort_index is not supported by old Pandas
Expand Down
4 changes: 2 additions & 2 deletions metrics/scripts/consistency.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,6 @@ def pp(n):
args.input_file,
skipinitialspace=True,
sep=r',\s+',
delimiter=',',
na_values='X')

# In the case of trailing whitespace, the X don't get converted.
Expand Down Expand Up @@ -167,7 +166,8 @@ def pp(n):
for (name, f) in measures.items():
measure = data_nona.apply(f, raw=True).copy()
measure.name = name
results = results.append(measure, ignore_index=False)
results = pd.concat([results, measure], axis=1, ignore_index=False)
results = results.transpose()

# Sort columns according to their PP value
# sort_index is not supported by old Pandas
Expand Down
71 changes: 43 additions & 28 deletions metrics/scripts/heatmap.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/usr/bin/python
#!/usr/bin/env python3
# Copyright (c) 2020 Performance Portability authors
# SPDX-License-Identifier: MIT

Expand Down Expand Up @@ -37,6 +37,8 @@

# Get the list of headings from first row
headings = data.fieldnames[1:]
if len(headings) < 1:
raise Exception("No input fields found")

# Name of the series, what the rows in the CSV actually are
series_key = data.fieldnames[0]
Expand All @@ -47,6 +49,13 @@
heatmap = [] # empty, to be populated by reading the input file
labels = [] # labels to display in each heatmap entry

plt.rc('text', usetex=True)
plt.rc('font', family='serif', serif='Times')
fig, ax = plt.subplots()

max_all = -np.inf
min_all = np.inf

for result in data:
def get(name):
str = result[name]
Expand All @@ -58,7 +67,7 @@ def get(name):
def eff(a, b):
if isinstance(a, float) and isinstance(b, float):
return float(100.0 * (a / b))
elif a is '-' or b is '-':
elif a == '-' or b == '-':
return float(-100.0)
else:
return float(0.0)
Expand All @@ -70,7 +79,9 @@ def eff(a, b):
continue

series.append(result[series_key])
heatmap.append([r if isinstance(r, float) else 0.0 for r in raw])
heatmap.append([r if isinstance(r, float) else float('nan') for r in raw])
max_all = max(max_all, max(heatmap[len(heatmap)-1]))
min_all = min(min_all, min(heatmap[len(heatmap)-1]))

l = []
for i in range(len(raw)):
Expand All @@ -79,57 +90,61 @@ def eff(a, b):
else:
if args.percent:
if plt.rcParams['text.usetex']:
l.append('%.0f\\%%' % (raw[i] / args.factorize))
if raw[i] / args.factorize < 100.0:
l.append('%.1f\\%%' % (raw[i] / args.factorize))
else:
l.append('%.0f\\%%' % (raw[i] / args.factorize))
else:
l.append('%.0f%%' % (raw[i] / args.factorize))
if raw[i] / args.factorize < 100.0:
l.append('%.1f%%' % (raw[i] / args.factorize))
else:
l.append('%.0f%%' % (raw[i] / args.factorize))
else:
if raw[i] / args.factorize < 100.0:
if not raw[i].is_integer():
l.append('%.1f' % (raw[i] / args.factorize))
else:
l.append('%.0f' % (raw[i] / args.factorize))
labels.append(l)

plt.rcParams.update({
"font.family": "serif", # use serif/main font for text elements
"text.usetex": False, # use inline math for ticks
"pgf.rcfonts": False, # don't setup fonts from rc parameters
})
fig, ax = plt.subplots()
fig.set_size_inches(4, 3)

# Set color map to match blackbody, growing brighter for higher values
colors = "gist_heat"
fig.set_figwidth(fig.get_figwidth() / 5 * len(l))
colors = "viridis"
Comment on lines 109 to +111
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the comment above this still accurate?

if not args.higher_is_better:
colors = colors + "_r"
cmap = plt.cm.get_cmap(colors)
x = np.arange(7)
y = np.arange(11)
cmap = plt.get_cmap(colors)
x = np.arange(len(l)+1)
y = np.arange(len(heatmap)+1)
masked = np.ma.masked_where(np.isnan(heatmap),heatmap)
cmesh = plt.pcolormesh(
x,
y,
np.array(heatmap),
masked,
cmap=cmap,
edgecolors='k',
vmin=1.0E-6)
ax.set_yticks(np.arange(len(heatmap)) + 0.5, minor=False)
ax.set_xticks(np.arange(len(heatmap[0])) + 0.5, minor=False)

ax.set_yticklabels(series)
ax.set_yticklabels(series, fontsize='xx-large')
for i in range(len(headings)):
heading = headings[i].replace('_', r'\_')
if not plt.rcParams['text.usetex']:
heading = heading.replace(r"\%", "%")
headings[i] = heading
ax.set_xticklabels(headings, rotation=45, ha="right", rotation_mode="anchor")
headings[i] = headings[i].replace('_', '\_')
ax.set_xticklabels(headings, fontsize='xx-large', rotation=45)
plt.gca().invert_yaxis()

# Add colorbar
plt.colorbar(cmesh)

one_third = max_all / 3.0
two_thirds = 2.0 * max_all / 3.0

# Add labels
for i in range(len(headings)):
for j in range(len(series)):
plt.text(i + 0.9, j + 0.5, labels[j][i],
ha='right', va='center', color='#b9c5bf', fontsize='small')
labelcolor = 'black'
if args.higher_is_better and heatmap[j][i] < one_third:
labelcolor='white'
elif not args.higher_is_better and heatmap[j][i] > two_thirds:
labelcolor='white'
plt.text(i + 0.5, j + 0.55, labels[j][i],
ha='center', va='center', color=labelcolor, weight='bold', size='xx-large')

plt.savefig(args.output, bbox_inches='tight')
4 changes: 2 additions & 2 deletions metrics/scripts/pp_vis.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/usr/bin/env python3.7
#!/usr/bin/env python3
# Copyright (c) 2020 Performance Portability authors
# SPDX-License-Identifier: MIT

Expand Down Expand Up @@ -232,7 +232,7 @@ def histogram(bins, data):
def binplot(ax, app_effs, colordict=None):
"""Compute and plot histogram of dataframe app_effs onto axis ax. Use colors for each column as specified in colordict or compute manually.
Bin 0 is handled specially and kept separate from others."""
bins = np.arange(0, 1.1, 0.1, dtype=np.float)
bins = np.arange(0, 1.1, 0.1, dtype=float)
bins[0] = np.finfo(float).eps
bins = np.append(np.zeros(1), bins)
bar_data = {}
Expand Down