-
-
Save robertguetzkow/f8feeef28ea8126daa23b7543bd64613 to your computer and use it in GitHub Desktop.
Image encoding benchmark for Blender's file formats
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import bpy | |
import os | |
import sys | |
import time | |
import statistics | |
import datetime | |
import random | |
from abc import ABC, abstractmethod | |
from typing import List | |
from contextlib import redirect_stdout | |
from mathutils import Vector | |
class FileSettings(ABC): | |
@abstractmethod | |
def activate(self): | |
pass | |
@abstractmethod | |
def configuration_string(self): | |
pass | |
def __hash__(self): | |
return hash(self.configuration_string()) | |
def __eq__(self, other): | |
return self.configuration_string() == other.configuration_string() | |
class BMP(FileSettings): | |
def __init__(self, color_mode="RGB"): | |
allowed_settings = { | |
"color_mode": {"BW", "RGB"} | |
} | |
self.label = "BMP" | |
self.extension = ".bmp" | |
self.settings = {} | |
if color_mode in allowed_settings["color_mode"]: | |
self.settings["color_mode"] = color_mode | |
def activate(self): | |
image_settings = bpy.context.scene.render.image_settings | |
image_settings.file_format = "BMP" | |
image_settings.color_mode = self.settings["color_mode"] | |
def configuration_string(self): | |
setting_str = self.label | |
setting_str += f" color_mode: {self.settings['color_mode']}" | |
return setting_str | |
class IRIS(FileSettings): | |
def __init__(self, color_mode="RGBA"): | |
allowed_settings = { | |
"color_mode": {"BW", "RGB", "RGBA"} | |
} | |
self.label = "IRIS" | |
self.extension = ".rgb" | |
self.settings = {} | |
if color_mode in allowed_settings["color_mode"]: | |
self.settings["color_mode"] = color_mode | |
def activate(self): | |
image_settings = bpy.context.scene.render.image_settings | |
image_settings.file_format = "IRIS" | |
image_settings.color_mode = self.settings["color_mode"] | |
def configuration_string(self): | |
setting_str = self.label | |
setting_str += f" color_mode: {self.settings['color_mode']}" | |
return setting_str | |
class PNG(FileSettings): | |
def __init__(self, color_mode="RGBA", color_depth="16", compression=100): | |
allowed_settings = { | |
"color_mode": {"BW", "RGB", "RGBA"}, | |
"color_depth": {"8", "16"}, | |
"compression": (0, 100) | |
} | |
self.label = "PNG" | |
self.extension = ".png" | |
self.settings = {} | |
if color_mode in allowed_settings["color_mode"]: | |
self.settings["color_mode"] = color_mode | |
if color_depth in allowed_settings["color_depth"]: | |
self.settings["color_depth"] = color_depth | |
if compression >= allowed_settings["compression"][0] and compression <= allowed_settings["compression"][1]: | |
self.settings["compression"] = compression | |
def activate(self): | |
image_settings = bpy.context.scene.render.image_settings | |
image_settings.file_format = "PNG" | |
image_settings.color_mode = self.settings["color_mode"] | |
image_settings.color_depth = self.settings["color_depth"] | |
image_settings.compression = self.settings["compression"] | |
def configuration_string(self): | |
setting_str = self.label | |
setting_str += f" color_mode: {self.settings['color_mode']}, " | |
setting_str += f"color_depth: {self.settings['color_depth']}, " | |
setting_str += f"compression: {self.settings['compression']}" | |
return setting_str | |
class JPEG(FileSettings): | |
def __init__(self, color_mode="RGB", quality=100): | |
allowed_settings = { | |
"color_mode": {"BW", "RGB"}, | |
"quality": (0, 100) | |
} | |
self.label = "JPEG" | |
self.extension = ".jpeg" | |
self.settings = {} | |
if color_mode in allowed_settings["color_mode"]: | |
self.settings["color_mode"] = color_mode | |
if quality >= allowed_settings["quality"][0] and quality <= allowed_settings["quality"][1]: | |
self.settings["quality"] = quality | |
def activate(self): | |
image_settings = bpy.context.scene.render.image_settings | |
image_settings.file_format = "JPEG" | |
image_settings.color_mode = self.settings["color_mode"] | |
image_settings.quality = self.settings["quality"] | |
def configuration_string(self): | |
setting_str = self.label | |
setting_str += f" color_mode: {self.settings['color_mode']}, " | |
setting_str += f"quality: {self.settings['quality']}" | |
return setting_str | |
class JPEG2000(FileSettings): | |
def __init__(self, color_mode="RGB", color_depth="16", quality=100, jpeg2k_codec="JP2", | |
use_jpeg2k_cinema_preset=False, use_jpeg2k_cinema_48=False, use_jpeg2k_ycc=False): | |
allowed_settings = { | |
"color_mode": {"BW", "RGB"}, | |
"color_depth": {"8", "12", "16"}, | |
"quality": (0, 100), | |
"jpeg2k_codec": {"JP2", "J2K"}, | |
"use_jpeg2k_cinema_preset": {True, False}, | |
"use_jpeg2k_cinema_48": {True, False}, | |
"use_jpeg2k_ycc": {True, False} | |
} | |
self.label = "J2K" | |
self.settings = {} | |
if color_mode in allowed_settings["color_mode"]: | |
self.settings["color_mode"] = color_mode | |
if color_depth in allowed_settings["color_depth"]: | |
self.settings["color_depth"] = color_depth | |
if quality >= allowed_settings["quality"][0] and quality <= allowed_settings["quality"][1]: | |
self.settings["quality"] = quality | |
if jpeg2k_codec in allowed_settings["jpeg2k_codec"]: | |
self.settings["jpeg2k_codec"] = jpeg2k_codec | |
if use_jpeg2k_cinema_preset in allowed_settings["use_jpeg2k_cinema_preset"]: | |
self.settings["use_jpeg2k_cinema_preset"] = use_jpeg2k_cinema_preset | |
if use_jpeg2k_cinema_48 in allowed_settings["use_jpeg2k_cinema_48"]: | |
self.settings["use_jpeg2k_cinema_48"] = use_jpeg2k_cinema_48 | |
if use_jpeg2k_ycc in allowed_settings["use_jpeg2k_ycc"]: | |
self.settings["use_jpeg2k_ycc"] = use_jpeg2k_ycc | |
if self.settings["jpeg2k_codec"] == "JP2": | |
self.extension = ".jp2" | |
else: | |
self.extension = ".j2c" | |
def activate(self): | |
image_settings = bpy.context.scene.render.image_settings | |
image_settings.file_format = "JPEG2000" | |
image_settings.color_mode = self.settings["color_mode"] | |
image_settings.color_depth = self.settings["color_depth"] | |
image_settings.quality = self.settings["quality"] | |
image_settings.jpeg2k_codec = self.settings["jpeg2k_codec"] | |
image_settings.use_jpeg2k_cinema_preset = self.settings["use_jpeg2k_cinema_preset"] | |
image_settings.use_jpeg2k_cinema_48 = self.settings["use_jpeg2k_cinema_48"] | |
image_settings.use_jpeg2k_ycc = self.settings["use_jpeg2k_ycc"] | |
def configuration_string(self): | |
setting_str = self.label | |
setting_str += f" color_mode: {self.settings['color_mode']}, " | |
setting_str += f"color_depth: {self.settings['color_depth']}, " | |
setting_str += f"quality: {self.settings['quality']}, " | |
setting_str += f"jpeg2k_codec: {self.settings['jpeg2k_codec']}, " | |
setting_str += f"use_jpeg2k_cinema_preset: {self.settings['use_jpeg2k_cinema_preset']}, " | |
setting_str += f"use_jpeg2k_cinema_48: {self.settings['use_jpeg2k_cinema_48']}, " | |
setting_str += f"use_jpeg2k_ycc: {self.settings['use_jpeg2k_ycc']}" | |
return setting_str | |
class TARGA(FileSettings): | |
def __init__(self, color_mode="RGBA"): | |
allowed_settings = { | |
"color_mode": {"BW", "RGB", "RGBA"} | |
} | |
self.label = "TARGA" | |
self.extension = ".tga" | |
self.settings = {} | |
if color_mode in allowed_settings["color_mode"]: | |
self.settings["color_mode"] = color_mode | |
def activate(self): | |
image_settings = bpy.context.scene.render.image_settings | |
image_settings.file_format = "TARGA" | |
image_settings.color_mode = self.settings["color_mode"] | |
def configuration_string(self): | |
setting_str = self.label | |
setting_str += f" color_mode: {self.settings['color_mode']}" | |
return setting_str | |
class TARGARaw(FileSettings): | |
def __init__(self, color_mode="RGBA"): | |
allowed_settings = { | |
"color_mode": {"BW", "RGB", "RGBA"} | |
} | |
self.label = "TARGA RAW" | |
self.extension = ".tga" | |
self.settings = {} | |
if color_mode in allowed_settings["color_mode"]: | |
self.settings["color_mode"] = color_mode | |
def activate(self): | |
image_settings = bpy.context.scene.render.image_settings | |
image_settings.file_format = "TARGA_RAW" | |
image_settings.color_mode = self.settings["color_mode"] | |
def configuration_string(self): | |
setting_str = self.label | |
setting_str += f" color_mode: {self.settings['color_mode']}" | |
return setting_str | |
class Cineon(FileSettings): | |
def __init__(self, color_mode="RGB"): | |
allowed_settings = { | |
"color_mode": {"RGB"} | |
} | |
self.label = "Cineon" | |
self.extension = ".cin" | |
self.settings = {} | |
if color_mode in allowed_settings["color_mode"]: | |
self.settings["color_mode"] = color_mode | |
def activate(self): | |
image_settings = bpy.context.scene.render.image_settings | |
image_settings.file_format = "CINEON" | |
image_settings.color_mode = self.settings["color_mode"] | |
def configuration_string(self): | |
setting_str = self.label | |
setting_str += f" color_mode: {self.settings['color_mode']}" | |
return setting_str | |
class DPX(FileSettings): | |
def __init__(self, color_mode="RGBA", color_depth="16", use_cineon_log=False): | |
allowed_settings = { | |
"color_mode": {"BW", "RGB", "RGBA"}, | |
"color_depth": {"8", "10", "12", "16"}, | |
"use_cineon_log": {True, False} | |
} | |
self.label = "DPX" | |
self.extension = ".dpx" | |
self.settings = {} | |
if color_mode in allowed_settings["color_mode"]: | |
self.settings["color_mode"] = color_mode | |
if color_depth in allowed_settings["color_depth"]: | |
self.settings["color_depth"] = color_depth | |
if use_cineon_log in allowed_settings["use_cineon_log"]: | |
self.settings["use_cineon_log"] = use_cineon_log | |
def activate(self): | |
image_settings = bpy.context.scene.render.image_settings | |
image_settings.file_format = "DPX" | |
image_settings.color_mode = self.settings["color_mode"] | |
image_settings.color_depth = self.settings["color_depth"] | |
image_settings.use_cineon_log = self.settings["use_cineon_log"] | |
def configuration_string(self): | |
setting_str = self.label | |
setting_str += f" color_mode: {self.settings['color_mode']}, " | |
setting_str += f"color_depth: {self.settings['color_depth']}, " | |
setting_str += f"use_cineon_log: {self.settings['use_cineon_log']}" | |
return setting_str | |
class OpenEXRMultilayer(FileSettings): | |
def __init__(self, color_mode="RGBA", color_depth="32", exr_codec="PIZ", use_preview=False): | |
allowed_settings = { | |
"color_mode": {"RGB", "RGBA"}, | |
"color_depth": {"16", "32"}, | |
"exr_codec": {"DWAA", "B44A", "ZIPS", "RLE", "PIZ", "ZIP", "PXR24", "NONE"}, | |
"use_preview": {True, False} | |
} | |
self.label = "OpenEXR Multilayer" | |
self.extension = ".exr" | |
self.settings = {} | |
if color_mode in allowed_settings["color_mode"]: | |
self.settings["color_mode"] = color_mode | |
if color_depth in allowed_settings["color_depth"]: | |
self.settings["color_depth"] = color_depth | |
if exr_codec in allowed_settings["exr_codec"]: | |
self.settings["exr_codec"] = exr_codec | |
if use_preview in allowed_settings["use_preview"]: | |
self.settings["use_preview"] = use_preview | |
def activate(self): | |
image_settings = bpy.context.scene.render.image_settings | |
image_settings.file_format = "OPEN_EXR_MULTILAYER" | |
image_settings.color_mode = self.settings["color_mode"] | |
image_settings.color_depth = self.settings["color_depth"] | |
image_settings.exr_codec = self.settings["exr_codec"] | |
image_settings.use_preview = self.settings["use_preview"] | |
def configuration_string(self): | |
setting_str = self.label | |
setting_str += f" color_mode: {self.settings['color_mode']}, " | |
setting_str += f"color_depth: {self.settings['color_depth']}, " | |
setting_str += f"exr_codec: {self.settings['exr_codec']}, " | |
setting_str += f"use_preview: {self.settings['use_preview']}" | |
return setting_str | |
class OpenEXR(FileSettings): | |
def __init__(self, color_mode="RGBA", color_depth="32", exr_codec="PIZ", use_zbuffer=False, use_preview=False): | |
allowed_settings = { | |
"color_mode": {"RGB", "RGBA"}, | |
"color_depth": {"16", "32"}, | |
"exr_codec": {"DWAA", "B44A", "ZIPS", "RLE", "PIZ", "ZIP", "PXR24", "NONE"}, | |
"use_zbuffer": {True, False}, | |
"use_preview": {True, False} | |
} | |
self.label = "OpenEXR" | |
self.extension = ".exr" | |
self.settings = {} | |
if color_mode in allowed_settings["color_mode"]: | |
self.settings["color_mode"] = color_mode | |
if color_depth in allowed_settings["color_depth"]: | |
self.settings["color_depth"] = color_depth | |
if exr_codec in allowed_settings["exr_codec"]: | |
self.settings["exr_codec"] = exr_codec | |
if use_zbuffer in allowed_settings["use_zbuffer"]: | |
self.settings["use_zbuffer"] = use_zbuffer | |
if use_preview in allowed_settings["use_preview"]: | |
self.settings["use_preview"] = use_preview | |
def activate(self): | |
image_settings = bpy.context.scene.render.image_settings | |
image_settings.file_format = "OPEN_EXR" | |
image_settings.color_mode = self.settings["color_mode"] | |
image_settings.color_depth = self.settings["color_depth"] | |
image_settings.exr_codec = self.settings["exr_codec"] | |
image_settings.use_zbuffer = self.settings["use_zbuffer"] | |
image_settings.use_preview = self.settings["use_preview"] | |
def configuration_string(self): | |
setting_str = self.label | |
setting_str += f" color_mode: {self.settings['color_mode']}, " | |
setting_str += f"color_depth: {self.settings['color_depth']}, " | |
setting_str += f"exr_codec: {self.settings['exr_codec']}, " | |
setting_str += f"use_zbuffer: {self.settings['use_zbuffer']}, " | |
setting_str += f"use_preview: {self.settings['use_preview']}" | |
return setting_str | |
class RadianceHDR(FileSettings): | |
def __init__(self, color_mode="RGB"): | |
allowed_settings = { | |
"color_mode": {"BW", "RGB"}, | |
} | |
self.label = "Radiance HDR" | |
self.extension = ".hdr" | |
self.settings = {} | |
if color_mode in allowed_settings["color_mode"]: | |
self.settings["color_mode"] = color_mode | |
def activate(self): | |
image_settings = bpy.context.scene.render.image_settings | |
image_settings.file_format = "HDR" | |
image_settings.color_mode = self.settings["color_mode"] | |
def configuration_string(self): | |
setting_str = self.label | |
setting_str += f" color_mode: {self.settings['color_mode']}" | |
return setting_str | |
class TIFF(FileSettings): | |
def __init__(self, color_mode="RGBA", color_depth="16", tiff_codec="DEFLATE"): | |
allowed_settings = { | |
"color_mode": {"BW", "RGB", "RGBA"}, | |
"color_depth": {"8", "16"}, | |
"tiff_codec": {"PACKBITS", "LZW", "DEFLATE", "NONE"} | |
} | |
self.label = "TIFF" | |
self.extension = ".tif" | |
self.settings = {} | |
if color_mode in allowed_settings["color_mode"]: | |
self.settings["color_mode"] = color_mode | |
if color_depth in allowed_settings["color_depth"]: | |
self.settings["color_depth"] = color_depth | |
if tiff_codec in allowed_settings["tiff_codec"]: | |
self.settings["tiff_codec"] = tiff_codec | |
def activate(self): | |
image_settings = bpy.context.scene.render.image_settings | |
image_settings.file_format = "TIFF" | |
image_settings.color_mode = self.settings["color_mode"] | |
image_settings.color_depth = self.settings["color_depth"] | |
image_settings.tiff_codec = self.settings["tiff_codec"] | |
def configuration_string(self): | |
setting_str = self.label | |
setting_str += f" color_mode: {self.settings['color_mode']}, " | |
setting_str += f"color_depth: {self.settings['color_depth']}, " | |
setting_str += f"tiff_codec: {self.settings['tiff_codec']}" | |
return setting_str | |
class Measurement(): | |
def __init__(self, filepath, file_settings: List[FileSettings]): | |
self.filepath = os.path.normpath(filepath) | |
self.filename = os.path.basename(self.filepath) | |
self.data = {} | |
self.output_size = {} | |
self.image_resolution = (0, 0) | |
for file_setting in file_settings: | |
self.data[file_setting] = [] | |
def add_result(self, file_settings, time, size): | |
self.data[file_settings].append(time) | |
self.output_size[file_settings] = size | |
def get_results(self, file_settings): | |
return self.data[file_settings] | |
def pretty_print(self): | |
print(f"------------------------------------------------------") | |
print(f"{self.filename}") | |
for file_settings, values in self.data.items(): | |
print(f" {file_settings.configuration_string()}") | |
print(f" {values}") | |
print(f" Output file size: {self.output_size[file_settings]}") | |
print(" ---------------------------------------------------") | |
class Benchmark(ABC): | |
@abstractmethod | |
def __init__(self, | |
filepaths: List[str], | |
file_settings: List[FileSettings], | |
result_directory, | |
measurements_per_file=10): | |
self.file_settings = file_settings | |
self.file_settings_original_order = file_settings.copy() | |
self.measurements_per_file = measurements_per_file | |
self.measurements = [Measurement(filepath, self.file_settings) for filepath in filepaths] | |
self.result_directory = os.path.normpath(result_directory) | |
def measure_for_file_settings(self, measurement, image): | |
# Shuffle to avoid benefits/downsides because of test order | |
random.shuffle(self.file_settings) | |
for file_setting in self.file_settings: | |
file_setting.activate() | |
output_filename = f"test{file_setting.extension}" | |
output_path = os.path.join(bpy.app.tempdir, output_filename) | |
for i in range(self.measurements_per_file): | |
start = time.time() | |
try: | |
image.save_render(output_path) | |
except: | |
print(f"Could not save image {output_filename}") | |
end = time.time() | |
time_passed = end - start | |
file_size = os.path.getsize(output_path) | |
measurement.add_result(file_setting, time_passed, file_size) | |
measurement.image_resolution = (image.size[0], image.size[1]) | |
@abstractmethod | |
def run(self): | |
pass | |
def save_results(self): | |
timestamp = datetime.datetime.now().strftime("%Y-%m-%d_%H%M%S") | |
try: | |
filename_time = f"{timestamp}_benchmark.svg" | |
filename_time_min = f"{timestamp}_benchmark_min.svg" | |
filename_size = f"{timestamp}_benchmark_size.svg" | |
result_file_time = os.path.join(self.result_directory, filename_time) | |
result_file_time_min = os.path.join(self.result_directory, filename_time_min) | |
result_file_size = os.path.join(self.result_directory, filename_size) | |
plot = Plot() | |
plot.time(result_file_time, self.measurements, self.file_settings_original_order) | |
plot.time_min(result_file_time_min, self.measurements, self.file_settings_original_order) | |
plot.file_size(result_file_size, self.measurements, self.file_settings_original_order) | |
except (ImportError, ModuleNotFoundError) as e: | |
print("Could not import matplotlib.") | |
filename = f"{timestamp}_benchmark.txt" | |
result_file = os.path.join(self.result_directory, filename) | |
with open(result_file, 'w') as f: | |
with redirect_stdout(f): | |
for measurement in self.measurements: | |
measurement.pretty_print() | |
class BenchmarkProject(Benchmark): | |
def __init__(self, | |
file_settings: List[FileSettings], | |
result_directory, | |
measurements_per_file=10): | |
super().__init__([bpy.data.filepath], file_settings, result_directory, measurements_per_file) | |
def measure_for_file_settings_render(self): | |
image = bpy.data.images["Render Result"] | |
self.measure_for_file_settings(self.measurements[0], image) | |
self.save_results() | |
def run(self): | |
bpy.ops.render.render() | |
self.measure_for_file_settings_render() | |
class BenchmarkImage(Benchmark): | |
def __init__(self, | |
filepaths: List[str], | |
file_settings: List[FileSettings], | |
result_directory, | |
measurements_per_file=10): | |
super().__init__(filepaths, file_settings, result_directory, measurements_per_file) | |
def run(self): | |
for measurement in self.measurements: | |
self.current_measurement = measurement | |
image = bpy.data.images.load(measurement.filepath, check_existing=False) | |
self.current_image = image | |
self.measure_for_file_settings(measurement, image) | |
image.user_clear() | |
bpy.data.images.remove(image) | |
self.save_results() | |
class Plot(): | |
def time(self, filepath: str, measurements: List[Measurement], file_settings: List[FileSettings]): | |
import matplotlib as mpl | |
mpl.use('Agg') | |
import matplotlib.pyplot as plt | |
import numpy as np | |
mean_values = {} | |
stdev_values = {} | |
x_labels = [] | |
for measurement in measurements: | |
res_x = measurement.image_resolution[0] | |
res_y = measurement.image_resolution[1] | |
x_labels.append( | |
f"{measurement.filename}\n({res_x}x{res_y})") | |
for file_setting in file_settings: | |
result = measurement.get_results(file_setting) | |
mean = statistics.mean(result) | |
stdev = statistics.stdev(result) | |
if mean_values.get(file_setting) is None: | |
mean_values[file_setting] = [] | |
mean_values[file_setting].append(mean) | |
if stdev_values.get(file_setting) is None: | |
stdev_values[file_setting] = [] | |
stdev_values[file_setting].append(stdev) | |
fig, ax = plt.subplots() | |
fig.set_size_inches(18.5, 10.5) | |
start = 1.0 | |
step = 10.0 | |
ind = np.linspace(start=start, stop=len(x_labels) * step, | |
num=len(x_labels)) | |
group_width = step | |
width = group_width / len(mean_values) | |
bars = [] | |
bars_legend = [] | |
counter = 0.0 | |
for file_setting, values in mean_values.items(): | |
stdev = stdev_values.get(file_setting) | |
loc_x = np.linspace(start=start - group_width / 2.0 + width * counter, | |
stop=len(x_labels) * step - group_width / 2.0 + width * counter, | |
num=len(values)) # num steps of values of particular format | |
bars.append(ax.bar(loc_x, values, width, bottom=0, yerr=stdev)) | |
bars_legend.append( | |
f"{file_setting.label}") | |
## Use for detailed configuration output in the legend | |
# f"{file_setting.configuration_string()}") | |
counter += 1.0 | |
ax.set_title('Benchmark Saving Times') | |
ax.set_xticks(ind - width / 2) | |
ax.set_xticklabels(x_labels) | |
ax.set_ylabel('Average saving time in seconds') | |
ax.set_xlabel('File') | |
ax.legend(bars, bars_legend, loc='upper left', bbox_to_anchor=(1.0, 1.01)) | |
ax.autoscale_view() | |
plt.grid(True) | |
plt.savefig(filepath, bbox_inches='tight', dpi=300) | |
def time_min(self, filepath: str, measurements: List[Measurement], file_settings: List[FileSettings]): | |
import matplotlib as mpl | |
mpl.use('Agg') | |
import matplotlib.pyplot as plt | |
import numpy as np | |
min_values = {} | |
x_labels = [] | |
for measurement in measurements: | |
res_x = measurement.image_resolution[0] | |
res_y = measurement.image_resolution[1] | |
x_labels.append( | |
f"{measurement.filename}\n({res_x}x{res_y})") | |
for file_setting in file_settings: | |
result = measurement.get_results(file_setting) | |
minimum = min(result) | |
if min_values.get(file_setting) is None: | |
min_values[file_setting] = [] | |
min_values[file_setting].append(minimum) | |
fig, ax = plt.subplots() | |
fig.set_size_inches(18.5, 10.5) | |
start = 1.0 | |
step = 10.0 | |
ind = np.linspace(start=start, stop=len(x_labels) * step, | |
num=len(x_labels)) | |
group_width = step | |
width = group_width / len(min_values) | |
bars = [] | |
bars_legend = [] | |
counter = 0.0 | |
for file_setting, values in min_values.items(): | |
loc_x = np.linspace(start=start - group_width / 2.0 + width * counter, | |
stop=len(x_labels) * step - group_width / 2.0 + width * counter, | |
num=len(values)) # num steps of values of particular format | |
bars.append(ax.bar(loc_x, values, width, bottom=0)) | |
bars_legend.append( | |
f"{file_setting.label}") | |
## Use for detailed configuration output in the legend | |
# f"{file_setting.configuration_string()}") | |
counter += 1.0 | |
ax.set_title('Benchmark Saving Times') | |
ax.set_xticks(ind - width / 2) | |
ax.set_xticklabels(x_labels) | |
ax.set_ylabel('Minimum saving time in seconds') | |
ax.set_xlabel('File') | |
ax.legend(bars, bars_legend, loc='upper left', bbox_to_anchor=(1.0, 1.01)) | |
ax.autoscale_view() | |
plt.grid(True) | |
plt.savefig(filepath, bbox_inches='tight', dpi=300) | |
def file_size(self, filepath: str, measurements: List[Measurement], file_settings: List[FileSettings]): | |
import matplotlib as mpl | |
mpl.use('Agg') | |
import matplotlib.pyplot as plt | |
import numpy as np | |
values = {} | |
x_labels = [] | |
for measurement in measurements: | |
res_x = measurement.image_resolution[0] | |
res_y = measurement.image_resolution[1] | |
x_labels.append( | |
f"{measurement.filename}\n({res_x}x{res_y})") | |
for file_setting in file_settings: | |
if values.get(file_setting) is None: | |
values[file_setting] = [] | |
value = measurement.output_size[file_setting] | |
value *= 0.000001 # Convert to MB | |
values[file_setting].append(value) | |
fig, ax = plt.subplots() | |
fig.set_size_inches(18.5, 10.5) | |
start = 1.0 | |
step = 10.0 | |
ind = np.linspace(start=start, stop=len(x_labels) * step, | |
num=len(x_labels)) | |
group_width = step | |
width = group_width / len(values) | |
bars = [] | |
bars_legend = [] | |
counter = 0.0 | |
for file_setting, value_entry in values.items(): | |
loc_x = np.linspace(start=start - group_width / 2.0 + width * counter, | |
stop=len(x_labels) * step - group_width / 2.0 + width * counter, | |
num=len(value_entry)) # num steps of values of particular format | |
bars.append(ax.bar(loc_x, value_entry, width, bottom=0)) | |
bars_legend.append( | |
f"{file_setting.label}") | |
## Use for detailed configuration output in the legend | |
# f"{file_setting.configuration_string()}") | |
counter += 1.0 | |
ax.set_title('Benchmark File Size') | |
ax.set_xticks(ind - width / 2) | |
ax.set_xticklabels(x_labels) | |
ax.set_ylabel('File size in MB') | |
ax.set_xlabel('File') | |
ax.legend(bars, bars_legend, loc='upper left', bbox_to_anchor=(1.0, 1.01)) | |
ax.autoscale_view() | |
plt.grid(True) | |
plt.savefig(filepath, bbox_inches='tight', dpi=300) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment