From 8031af626c88ed839ba94b21d226d98281882634 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Buchwald?= Date: Sat, 23 Mar 2024 00:55:59 +0100 Subject: [PATCH] improve appearance --- ogs-monitor.py | 99 +++++++++++++++++++++++++++++++++++++------------ ogs.png | Bin 0 -> 24471 bytes 2 files changed, 76 insertions(+), 23 deletions(-) create mode 100644 ogs.png diff --git a/ogs-monitor.py b/ogs-monitor.py index eb7789a..b3ed051 100644 --- a/ogs-monitor.py +++ b/ogs-monitor.py @@ -1,7 +1,14 @@ +import os import sys import warnings import time +try: + from PIL import Image + imagemodule = True +except ModuleNotFoundError: + print("module Image not installed") + imagemodule = False import matplotlib.pyplot as plt import matplotlib.animation as animation from matplotlib import style @@ -45,14 +52,31 @@ def __init__(self, logfile, reffile, update_interval, window_length, maximum_lin else: for j, filt in enumerate(self.filters): self.logfile_ref_df[j] = None + self.q0_xb = None + self.q0_yb = None + self.q1_xb = None + self.q1_yb = None + self.q2_xb = None + self.q2_yb = None + self.q3_xb = None + self.q3_yb = None self.plot_init() self.plot() + def plot_init(self): style.use('fast') if self.show_quadrant == -1: self.fig, self.axs = plt.subplots(2,2) else: self.fig, self.axs = plt.subplots(1,1) + if imagemodule is True: + dirname = os.path.dirname(__file__) + im = Image.open(os.path.join(dirname, "ogs.png")) + height = im.size[1] + width = im.size[0] + newsize = (int(width/2), int(height/2)) + im = im.resize(newsize) + self.fig.figimage(im, 0, 0, alpha=0.5) def map_quadrant_rqfilter(self, j): if j == 3: return True @@ -69,7 +93,8 @@ def map_quadrant_rqfilter(self, j): else: return False def plot(self): - def animate(_): + def animate(m): + print(m) logfile_df = {} start = time.time() records = parser.parse_file(self.log_file, maximum_lines=self.maximum_lines, force_parallel=False) @@ -112,12 +137,18 @@ def animate(_): else: ax = self.axs ax.clear() + #ax.spines['top'].set_visible(False) not working + #ax.spines['right'].set_visible(False) ax.plot(logfile_df[0]["time_step"], logfile_df[0]["iteration_number"], 'b', label="actual log") - axs12 = ax.twiny() + if self.q1_yb is None: + self.q1_yb = ax.twiny() + self.q1_yb.get_legend_handles_labels() + #self.q1_yb.get_yaxis().set_visible(False) if not self.logfile_ref_df[0] is None: - axs12.plot(self.logfile_ref_df[0]["time_step"], self.logfile_ref_df[0]["iteration_number"], 'k', label="reference data") + #self.q1_yb.get_yaxis().set_visible(False) + self.q1_yb.plot(self.logfile_ref_df[0]["time_step"], self.logfile_ref_df[0]["iteration_number"], 'k', label="reference data") ax.set(xlabel="time step", ylabel="iterations") - lines, labels = axs12.get_legend_handles_labels() + lines, labels = self.q1_yb.get_legend_handles_labels() lines2, labels2 = ax.get_legend_handles_labels() ax.legend(lines + lines2, labels + labels2, loc=0) ax.set_title("iterations per time step") @@ -127,15 +158,27 @@ def animate(_): ax = self.axs[0,1] else: ax = self.axs - ax.clear() - ax.plot(logfile_df[1]["time_step"], logfile_df[1]["step_size"], 'b', label="actual log") - axs22 = ax.twiny() + #ax.spines['top'].set_visible(False) + for entry in ax.get_shared_x_axes().get_siblings(ax): + entry.clear() + ax.plot(logfile_df[1]["time_step"], logfile_df[1]["step_size"], 'b-', label="time step (actual)") + if self.q0_yb is None: + self.q0_yb = ax.twiny() + #self.q0_yb.get_yaxis().set_visible(False) if not self.logfile_ref_df[1] is None: - axs22.plot(self.logfile_ref_df[1]["time_step"], self.logfile_ref_df[1]["step_size"], 'k', label="reference data") - lines, labels = axs22.get_legend_handles_labels() + #self.q0_yb.get_yaxis().set_visible(True) + self.q0_yb.plot(self.logfile_ref_df[1]["time_step"], self.logfile_ref_df[1]["step_size"], 'k-', label="time step (reference)") + if self.q0_xb is None: + self.q0_xb = ax.twinx() + self.q0_xb.plot(logfile_df[1]["time_step"], logfile_df[1]["step_start_time"], 'r-', label="start time (actual)") + self.q0_xb.set_ylabel("time / s", color="r") + self.q0_xb.yaxis.set_label_position("right") + lines, labels = self.q0_yb.get_legend_handles_labels() lines2, labels2 = ax.get_legend_handles_labels() - ax.legend(lines + lines2, labels + labels2, loc=0) - ax.set(xlabel="time step", ylabel="step size") + lines3, labels3 = self.q0_xb.get_legend_handles_labels() + ax.legend(lines + lines2 + lines3, labels + labels2 + labels3, loc=0) + ax.set_xlabel("time step") + ax.set_ylabel("step size", color='b') ax.set_title("time step sizes") if ((self.show_quadrant == -1) or (self.show_quadrant == 2)): @@ -146,11 +189,14 @@ def animate(_): ax.clear() ax.plot(logfile_df[1]["time_step"],logfile_df[1]["assembly_time"],"b-", label="assembly time (actual)") ax.plot(logfile_df[1]["time_step"],logfile_df[1]["linear_solver_time"], "g-", label="linear solver time (actual)") - axs32 = ax.twiny() + if self.q2_yb is None: + self.q2_yb = ax.twiny() + #self.q2_yb.get_yaxis().set_visible(False) if not self.logfile_ref_df[1] is None: - axs32.plot(self.logfile_ref_df[1]["time_step"], self.logfile_ref_df[1]["assembly_time"], "b--", label="assembly time (ref)") - axs32.plot(self.logfile_ref_df[1]["time_step"], self.logfile_ref_df[1]["linear_solver_time"], "g--", label="linear solver time (ref)") - lines, labels = axs32.get_legend_handles_labels() + #self.q2_yb.get_yaxis().set_visible(True) + self.q2_yb.plot(self.logfile_ref_df[1]["time_step"], self.logfile_ref_df[1]["assembly_time"], "b--", label="assembly time (ref)") + self.q2_yb.plot(self.logfile_ref_df[1]["time_step"], self.logfile_ref_df[1]["linear_solver_time"], "g--", label="linear solver time (ref)") + lines, labels = self.q2_yb.get_legend_handles_labels() lines2, labels2 = ax.get_legend_handles_labels() ax.legend(lines + lines2, labels + labels2, loc=0) ax.set(xlabel="time step", ylabel="time / s") @@ -207,14 +253,17 @@ def update_ticks_ref(x, pos): ax = self.axs ax.clear() ax.plot(newindex, logfile_df[2][logfile_df[2]["component"]==self.crit_comp][self.crit], 'b', label="actual") - axs42 = ax.twiny() + if self.q3_yb is None: + self.q3_yb = ax.twiny() + #self.q3_yb.get_yaxis().set_visible(False) if not self.logfile_ref_df[2] is None: - axs42.plot(newindex_ref, self.logfile_ref_df[2][self.logfile_ref_df[2]["component"]==self.crit_comp][self.crit], 'k', label="reference") - axs42.xaxis.set_major_formatter(mticker.FuncFormatter(update_ticks_ref)) - sec_ref = axs42.secondary_xaxis(location=1) + #self.q3_yb.get_yaxis().set_visible(True) + self.q3_yb.plot(newindex_ref, self.logfile_ref_df[2][self.logfile_ref_df[2]["component"]==self.crit_comp][self.crit], 'k', label="reference") + self.q3_yb.xaxis.set_major_formatter(mticker.FuncFormatter(update_ticks_ref)) + sec_ref = self.q3_yb.secondary_xaxis(location=1) sec_ref.set_xticks(newindex2_ref, labels=time_data_ref) sec_ref.tick_params('x', length=0) - lines, labels = axs42.get_legend_handles_labels() + lines, labels = self.q3_yb.get_legend_handles_labels() lines2, labels2 = ax.get_legend_handles_labels() ax.legend(lines + lines2, labels + labels2, loc=0) ax.set(xlabel="\n\ntime step", ylabel=self.crit) @@ -225,13 +274,17 @@ def update_ticks_ref(x, pos): sec.set_xticks(newindex2, labels=time_data) sec.tick_params('x', length=0) if self.running is True: - self.fig.suptitle("OGS Monitor\n(OGS running)") + try: + self.fig.suptitle(f"OGS running\n({logfile_df[1]['time_step_solution_time'].sum()} s)") + except: + self.fig.suptitle("OGS running") else: - self.fig.suptitle(f"OGS Monitor\n(OGS excec time: {logfile_df[3]['execution_time'].iloc[0]} s)") + self.fig.suptitle(f"OGS finished\n({logfile_df[3]['execution_time'].iloc[0]} s)") stop = time.time() print(f"plot {stop-start} s") ani = animation.FuncAnimation(self.fig, animate, interval=self.interval) - plt.tight_layout() + #äplt.tight_layout(pad=0.4, w_pad=0.5, h_pad=1.0) + plt.subplots_adjust(plt.subplots_adjust(top=0.9, bottom=0.1, left=0.1, right=0.9, hspace=0.3, wspace=0.2)) plt.show() diff --git a/ogs.png b/ogs.png new file mode 100644 index 0000000000000000000000000000000000000000..92cc0721b3aa049325805bae6678c923f35a8252 GIT binary patch literal 24471 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