memgraph/tools/plot_ldbc_latency

148 lines
5.7 KiB
Plaintext
Raw Normal View History

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
'''
Latency Barchart (Based on LDBC JSON output).
'''
import json
import os
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.cbook import get_sample_data
from argparse import ArgumentParser
SCRIPT_DIR = os.path.dirname(os.path.realpath(__file__))
COLORS = {
'memgraph': '#ff7300',
'neo4j': '#008cc2'
}
def parse_args():
argp = ArgumentParser(description=__doc__)
argp.add_argument("--vendor-references", nargs="+",
help="Short references that represent all the "
"vendors that are going to be "
"visualized on the plot.")
argp.add_argument("--vendor-titles", nargs="+",
help="Vender titles that are going to appear "
"on the plot, e.g. legend titles.")
argp.add_argument("--plot-title", default="{{Plot title placeholder}}",
help="Plot title.")
argp.add_argument("--logo-path", default=None,
help="Path to the logo that is going to be presented"
" instead of title.")
argp.add_argument("--results-dir",
default=os.path.join(SCRIPT_DIR,
"../tests/public_benchmark"
"/ldbc/results"),
help="Path to the folder with result files in format "
"{{vendor-reference}}-LDBC-results.json")
argp.add_argument("--max-label-width", default=11, type=int,
help="Maximum length of the x-axis labels (-1 is unlimited)")
return argp.parse_args()
def autolabel(ax, rects):
"""
Attach a text label above each bar displaying its height
"""
for rect in rects:
height = rect.get_height()
# TODO: adjust more vendors
ax.text(rect.get_x() + rect.get_width()/2., 1.00*height,
'%d' % int(height),
ha='center', va='bottom')
def main():
# Read the arguments.
args = parse_args()
# Prepare the datastructure.
vendors = {}
for vendor_reference, vendor_title in zip(args.vendor_references,
args.vendor_titles):
vendors[vendor_reference] = {}
vendors[vendor_reference]['title'] = vendor_title
vendors[vendor_reference]['results_path'] = os.path.join(
args.results_dir, "%s-LDBC-results.json" % vendor_reference)
vendors[vendor_reference]['color'] = COLORS[vendor_reference]
vendors[vendor_reference]['latencies'] = []
vendors[vendor_reference]['query_names'] = []
assert len(vendors) == 2, "The graph is tailored for only 2 vendors."
# Collect the benchmark data.
print("LDBC Latency Data")
for vendor_reference, vendor_data in vendors.items():
print("Vendor: %s" % vendor_reference)
with open(vendor_data['results_path']) as results_file:
results_data = json.load(results_file)
for query_data in results_data["all_metrics"]:
mean_runtime = query_data["run_time"]["mean"]
query_name = query_data['name']
print("%s -> %sms" % (query_name, str(mean_runtime)))
vendor_data['latencies'].append(mean_runtime)
vendor_data['query_names'].append(query_name)
# Consistency check.
all_query_names = [tuple(vd['query_names']) for vd in vendors.values()]
assert len(set(all_query_names)) == 1, \
"Queries between different vendors are different!"
query_names = all_query_names[0]
# Plot.
ind = np.arange(len(query_names)) # the x locations for the groups
width = 0.40 # the width of the bars
fig, ax = plt.subplots() # figure setup
ax.set_ylabel('Mean Latency (ms)') # YAxis title
ax.set_facecolor('#dcdcdc') # plot bg color (light gray)
ax.set_xticks(ind + width / len(vendors)) # TODO: adjust (more vendors)
def shorten_query_name(query_name):
# Long query names on the x-axis don't look compelling.
if query_name.lower().startswith('ldbc'):
query_name = query_name[4:]
if len(query_name) > args.max_label_width:
query_name = query_name[:args.max_label_width] + '\N{HORIZONTAL ELLIPSIS}'
return query_name
labels = query_names
if args.max_label_width == 0:
labels = ["Q{}".format(i) for i, _ in enumerate(query_names)]
elif args.max_label_width > 0:
labels = map(shorten_query_name, query_names)
ax.set_xticklabels(labels, rotation=30)
# set only horizontal grid lines
for line in ax.get_xgridlines():
line.set_linestyle(' ')
for line in ax.get_ygridlines():
line.set_linestyle('--')
ax.set_axisbelow(True) # put the grid below all other elements
plt.grid(True) # show grid
# Draw logo or plot title
if args.logo_path is None:
ax.set_title(args.plot_title)
else:
# TODO: improve the logo positioning
im = plt.imread(get_sample_data(args.logo_path))
plt.gcf().subplots_adjust(top=0.85)
newax = fig.add_axes([0.4, 0.75, 0.2, 0.25], anchor='N')
newax.imshow(im)
newax.axis('off')
# Draw bars
for index, vendor_data in enumerate(vendors.values()):
rects = ax.bar(ind + index * width, vendor_data['latencies'], width,
color=vendor_data['color'])
vendor_data['rects'] = rects
autolabel(ax, rects)
rects = [vd['rects'][0] for vd in vendors.values()]
titles = [vd['title'] for vd in vendors.values()]
ax.legend(rects, titles) # Draw the legend.
plt.show()
if __name__ == '__main__':
main()