Files
MapLibreParticleLab/scripts/aws-device-farm/plot-android-benchmark-results.py
Bart Louwers c79b6dcf52 Add end-of-file-fixer pre-commit hook (#3176)
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2025-01-24 20:43:50 +01:00

99 lines
3.2 KiB
Python

import sqlite3
import matplotlib.pyplot as plt
import numpy as np
import math
import argparse
parser = argparse.ArgumentParser("plot-android-benchmark-results")
parser.add_argument("db", help="Path to SQLite database with results", type=str)
args = parser.parse_args()
# Connect to the SQLite database
conn = sqlite3.connect(args.db) # Replace with your database file path
cursor = conn.cursor()
# Query to get the average FPS and variance for each style, renderer, and model where syncRendering=0
query = """
SELECT deviceManufacturer, model, styleName, renderer,
AVG(fps) AS avg_fps,
(
AVG(fps * fps) - AVG(fps) * AVG(fps)
) AS variance_fps
FROM benchmark_result
WHERE syncRendering = 0
GROUP BY deviceManufacturer, model, styleName, renderer
ORDER BY deviceManufacturer, model, styleName, renderer
"""
# Execute the query
cursor.execute(query)
rows = cursor.fetchall()
# Close the connection to the database
conn.close()
# Organize the data into a dictionary for plotting
data = {}
for row in rows:
manufacturer, model, style, renderer, avg_fps, variance_fps = row
device = f"{manufacturer} {model}"
if device not in data:
data[device] = {}
if style not in data[device]:
data[device][style] = {'fps': [], 'stddev': []}
stddev_fps = math.sqrt(max(variance_fps, 0)) # Calculate the standard deviation and ensure it's not negative
data[device][style]['fps'].append((renderer, avg_fps))
data[device][style]['stddev'].append((renderer, stddev_fps))
# Define the colors for each renderer
colors = {'legacy': 'gray', 'drawable': 'blue', 'vulkan': 'red'}
renderer_order = ['legacy', 'drawable', 'vulkan']
legend_names = {'legacy': 'Legacy', 'drawable': 'OpenGL', 'vulkan': 'Vulkan'}
# Create subplots for each device
num_devices = len(data)
fig, axes = plt.subplots(num_devices, 1, figsize=(10, 6 * num_devices))
if num_devices == 1:
axes = [axes]
# Plot data for each device
for ax, (device, styles) in zip(axes, data.items()):
# Get a sorted list of styles
style_names = sorted(styles.keys())
# Number of styles
n_styles = len(style_names)
# Create an array with the position of each group of bars
bar_width = 0.25
index = np.arange(n_styles)
# Plot each renderer's bar with error bars in the defined order
for i, renderer in enumerate(renderer_order):
avg_fps_values = []
stddev_values = []
for style in style_names:
fps_values = dict(styles[style]['fps'])
stddev_values_dict = dict(styles[style]['stddev'])
# Use get to return a default of 0 if the renderer is not present
avg_fps_values.append(fps_values.get(renderer, 0))
stddev_values.append(stddev_values_dict.get(renderer, 0))
ax.bar(index + i * bar_width, avg_fps_values, bar_width, yerr=stddev_values,
label=legend_names[renderer], color=colors[renderer], capsize=5, error_kw={'elinewidth': 1, 'ecolor': 'black'})
# Set the title, labels, ticks, etc.
ax.set_title(device)
ax.set_xlabel('Style')
ax.set_ylabel('Average FPS')
ax.set_xticks(index + bar_width)
ax.set_xticklabels(style_names)
ax.legend(title='Renderer')
# Adjust layout
plt.tight_layout()
# Show the plot
plt.savefig('plot.png')