From faf6cd5d2ad944bf4c6470506d895e5d9bd0f6b6 Mon Sep 17 00:00:00 2001 From: Guillaume Raffy Date: Tue, 23 Feb 2021 15:40:01 +0000 Subject: [PATCH] =?UTF-8?q?Bug=203098=20-=20mettre=20=C3=A0=20jour=20les?= =?UTF-8?q?=20graphiques=20montrant=20l'=C3=A9volution=20du=20cluster?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - improved the handling of colors. As a result, the number of owners is no longer restricted, as the color palette is now no longer restricted in size - improved readability by putting the legend on the upper left part of the graphs, where it no longer hides the upper right part of the graph - fixed clutter of years on the x axis which made it difficult to read the years. Now, there is a limit in the number of years displayed on the x axis - improved the legend showng the owners, which now displays the lab in addition to the department --- cluster_stats.py | 36 +++++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/cluster_stats.py b/cluster_stats.py index 15a0289..047b2fd 100644 --- a/cluster_stats.py +++ b/cluster_stats.py @@ -4,6 +4,7 @@ import os import re import datetime import numpy as np +import colorsys # fix to prevent the following error when run from www-data # Failed to create /var/www/.matplotlib; consider setting MPLCONFIGDIR to a writable directory for matplotlib configuration data # root@intranet:~# echo ~www-data @@ -116,18 +117,26 @@ def get_computer_value_over_time(inventory, computer_id, time_value, flops_price # plt.legend() -def stackplot(ax, x_signal, y_signals): +def get_rgb_palette(num_colors, saturation=0.5, value=0.5): + hsv_tuples = [(x * 1.0 / num_colors, saturation, value) for x in range(num_colors)] + rgb_tuples = map(lambda x: colorsys.hsv_to_rgb(*x), hsv_tuples) + return rgb_tuples + + +def stackplot(ax, x_signal, y_signals, legend_location='best'): """ :param matplotlib.Axes ax: :param numpy.array x_signal: :param dict(str,numpy.array) y_signals: + :param str legend_location: one of the values allowed in loc argument of matplotlib's plt.legend() function, or: + 'outside right': outside the graph, at its right """ if 'stackplot' in dir(ax): ax.stackplot(x_signal, list(y_signals.values())) plt.legend(list(y_signals.keys())) else: # emulating missing Axes.stackplot method - colors = ['blue', 'orange', 'green', 'purple', 'yellow'] + colors = get_rgb_palette(num_colors=len(y_signals), saturation=1.0, value=0.8) # ['blue', 'orange', 'green', 'purple', 'yellow', 'cyan'] y = np.row_stack(list(y_signals.itervalues())) # this call to 'cumsum' (cumulative sum), passing in your y data, # is necessary to avoid having to manually order the datasets @@ -140,7 +149,11 @@ def stackplot(ax, x_signal, y_signals): ax.fill_between(x_signal, from_signal, y_stack[series_index, :], color=colors[series_index], lw=0.0) p = plt.Rectangle((0, 0), 0, 0, color=colors[series_index]) ax.add_patch(p) - plt.legend(list(y_signals.keys())) + + if legend_location == 'outside right': + plt.legend(list(y_signals.keys()), bbox_to_anchor=(1.10, 1.00), loc='upper left') # force the legend into the bounding box + else: + plt.legend(list(y_signals.keys()), loc=legend_location) def draw_cluster_value_over_time_graph(inventory, from_date, to_date, graph_type): @@ -166,7 +179,7 @@ def draw_cluster_value_over_time_graph(inventory, from_date, to_date, graph_type # print(ownership) # print(ownership['owner'], ownership['owner_ratio']) owner = ownership['owner'] - owner_dept = owner.split('.')[1] + owner_dept = '.'.join(owner.split('.')[0:2]) # if owner_dept == 'matnano': # print(name, owner, purchase_date, price_ex_vat) if owner_dept in cluster_value.keys(): @@ -185,7 +198,7 @@ def draw_cluster_value_over_time_graph(inventory, from_date, to_date, graph_type # for dept, cluster_value_for_dept in cluster_value.iteritems(): # ax.plot(time_value, cluster_value_for_dept) - stackplot(ax, time_value, cluster_value) + stackplot(ax, time_value, cluster_value, legend_location='upper left') plt.xlabel('time') plt.ylabel({ @@ -193,7 +206,15 @@ def draw_cluster_value_over_time_graph(inventory, from_date, to_date, graph_type 'cluster_value_over_time': u'cluster value (€)', 'cluster_dp_gflops_over_time': u'double prec gflops'}[graph_type]) - years = matplotlib.dates.YearLocator() # every year + datemin = datetime.date(from_date.year, 1, 1) + datemax = datetime.date(to_date.year + 1, 1, 1) + ax.set_xlim(datemin, datemax) + + max_num_years = 8 + num_years = (datemax - datemin).days // 365 + year_step = num_years / max_num_years + + years = matplotlib.dates.YearLocator(year_step) # every year_step year months = matplotlib.dates.MonthLocator() # every month yearsFmt = matplotlib.dates.DateFormatter('%Y') @@ -202,9 +223,6 @@ def draw_cluster_value_over_time_graph(inventory, from_date, to_date, graph_type ax.xaxis.set_major_formatter(yearsFmt) ax.xaxis.set_minor_locator(months) - datemin = datetime.date(from_date.year, 1, 1) - datemax = datetime.date(to_date.year + 1, 1, 1) - ax.set_xlim(datemin, datemax) # rotates and right aligns the x labels, and moves the bottom of the # axes up to make room for them