This commit is contained in:
Yannik Schmidt
2020-08-16 16:32:01 +02:00
parent 2e9eb9864b
commit 72d7d7a4a1

View File

@@ -12,32 +12,54 @@ import timeutils
matplotlib.rc('font', **GLOBAL_FONT) matplotlib.rc('font', **GLOBAL_FONT)
def getlimits_y(y): def getlimits_y(y):
'''Get tuple of (ymin, ymax) based on configuration'''
# calculate actual values #
ymax = max(y) + CFG("empty_space_above_plot") ymax = max(y) + CFG("empty_space_above_plot")
y_min_height = CFG("yaxis_minnimum_hight") y_min_height = CFG("yaxis_minnimum_hight")
# allow negative values when nessesary #
if y_min_height != 0 and y_min_height > ymax: if y_min_height != 0 and y_min_height > ymax:
ymax = y_min_height ymax = y_min_height
y_start_val = CFG("yaxis_start_value") y_start_val = CFG("yaxis_start_value")
# force start value if set in configuration #
if y_start_val < min(y) or ( CFG("yaxis_force_start_value") and not min(y) < 0): if y_start_val < min(y) or ( CFG("yaxis_force_start_value") and not min(y) < 0):
ymin = y_start_val ymin = y_start_val
else: else:
ymin = min(y) ymin = min(y)
return (ymin, ymax) return (ymin, ymax)
def avg(array):
return sum(array)/float(len(array))
def legend_box_contents(name, y): def legend_box_contents(name, y):
'''Return a string with the formate content of the legend/caption'''
# capping values at 99 makes formating easier#
if CFG("cap_values_at_99"): if CFG("cap_values_at_99"):
y = [ min( [el, 99.9] ) for el in y ] y = [ min( [el, 99.9] ) for el in y ]
# add minimum values if configured #
if CFG("show_min"): if CFG("show_min"):
name += " min: {:4.1f},".format(min(y)) name += " min: {:4.1f},".format(min(y))
# add maximum values if configured #
if CFG("show_max"): if CFG("show_max"):
name += " max: {:4.1f},".format(max(y)) name += " max: {:4.1f},".format(max(y))
# show average if configured #
if CFG("show_avg"): if CFG("show_avg"):
name += " Mittelwert: {:4.1f},".format(avg(y)) name += " Mittelwert: {:4.1f},".format(sum(y)/float(len(y)))
return name.rstrip(",") return name.rstrip(",")
def general_background_setup(tup,ymin,ymax,x): def general_background_setup(tup,ymin,ymax,x):
'''Setup the Canvas:
- set x/y scala limits
- draw warning lines/areas
- calculate and draw gridsetps
- calculate and draw x/y ticks
- draw labels
- draw caption
'''
unix_x = [ el.timestamp() for el in x ] unix_x = [ el.timestamp() for el in x ]
@@ -45,24 +67,39 @@ def general_background_setup(tup,ymin,ymax,x):
tup[AXIS].set_ylim( [ ymin, ymax ] ) tup[AXIS].set_ylim( [ ymin, ymax ] )
tup[AXIS].set_xlim( [ min(x).timestamp(), max(x).timestamp() ] ) tup[AXIS].set_xlim( [ min(x).timestamp(), max(x).timestamp() ] )
### draw warning lines/areas ###
if CFG("draw_thresholds"): if CFG("draw_thresholds"):
hcrit=CFG("humidity_critical")
hwarn=CFG("humidity_warning")
tlow=CFG("acceptable_temp_low")
thigh=CFG("acceptable_temp_high")
tup[AXIS].axhline(y=CFG("target_temperatur"),ls=CFG("hline_line_style"),lw=CFG("hline_line_width"),color=CFG("acceptable_temp_color"))
tup[AXIS].axhline(y=hcrit,ls=CFG("hline_line_style"),lw=CFG("hline_line_width"),color=CFG("humidity_crit_color"))
tup[AXIS].axhspan(hwarn,hcrit,color=CFG("humidity_warning_color"),alpha=CFG("humidity_warning_alpha"))
tup[AXIS].axhspan(hcrit,ymax,color=CFG("humidity_crit_color"),alpha=CFG("humidity_crit_alpha"))
tup[AXIS].axhspan(tlow,thigh,color=CFG("acceptable_temp_color"),alpha=CFG("acceptable_temp_alpha"))
#### GRID #### humCrit = CFG("humidity_critical")
humWarn = CFG("humidity_warning")
tempLow = CFG("acceptable_temp_low")
tempHigh = CFG("acceptable_temp_high")
tempOptimal = CFG("target_temperatur")
hLineStyle = CFG("hline_line_style")
hLineWidth = CFG("hline_line_width")
tempOptimalColor = CFG("acceptable_temp_color")
tempOptimalAlpha = CFG("acceptable_temp_alpha")
humCritColor = CFG("humidity_crit_color")
humWarnColor = CFG("humidity_warning_color")
humCritAlpha = CFG("humidity_crit_alpha")
humWarnAlpha = CFG("humidity_warning_alpha")
tup[AXIS].axhline(y=tempOptimal, ls=hLineStyle, lw=hLineWidth, color=tempOptimalColor)
tup[AXIS].axhline(y=humCrit, ls=hLineStyle, lw=hLineWidth, color=humCritColor)
tup[AXIS].axhspan(humWarn, humCrit, color=humWarnColor, alpha=humWarnAlpha)
tup[AXIS].axhspan(humCrit, ymax, color=humCritColor, alpha=humCritAlpha)
tup[AXIS].axhspan(tempLow, tempHigh, color=tempOptimalColor, alpha=tempOptimalAlpha)
#### setup grid ####
major_xticks = gen_xticks_from_timeseries(x) major_xticks = gen_xticks_from_timeseries(x)
minor_xticks = get_minor_xticks_from_major(major_xticks) minor_xticks = get_minor_xticks_from_major(major_xticks)
if CFG("raster"): if CFG("raster"):
grid(tup, major_xticks, ymin, ymax) grid(tup, major_xticks, ymin, ymax)
#### XTICKS #### #### setup xticks ####
tup[AXIS].set_xticks(major_xticks) tup[AXIS].set_xticks(major_xticks)
tup[AXIS].xaxis.set_major_formatter(ticker.FuncFormatter(xlabel_formater_callback)) tup[AXIS].xaxis.set_major_formatter(ticker.FuncFormatter(xlabel_formater_callback))
tup[AXIS].xaxis.set_major_locator(ticker.FixedLocator(major_xticks, nbins=None)) tup[AXIS].xaxis.set_major_locator(ticker.FixedLocator(major_xticks, nbins=None))
@@ -76,12 +113,12 @@ def general_background_setup(tup,ymin,ymax,x):
tup[AXIS].tick_params(axis='x', which="major", labelsize=CFG("xticks_font_size")); tup[AXIS].tick_params(axis='x', which="major", labelsize=CFG("xticks_font_size"));
tup[AXIS].tick_params(axis='y', which="major", labelsize=CFG("yticks_font_size")); tup[AXIS].tick_params(axis='y', which="major", labelsize=CFG("yticks_font_size"));
## ROTATION XLABELS ## ### roate xtick-labels to 45deg ###
rotation=CFG("xticks_label_degree") rotation=CFG("xticks_label_degree")
if rotation > 0: if rotation > 0:
plt.xticks(rotation=rotation,ha='right') plt.xticks(rotation=rotation,ha='right')
## AXIS LABELS ### setup axis labels ###
ylabel_box = dict(boxstyle="square", facecolor='grey', alpha=0.4, edgecolor='black', lw=0.5) ylabel_box = dict(boxstyle="square", facecolor='grey', alpha=0.4, edgecolor='black', lw=0.5)
xlabel_box = ylabel_box xlabel_box = ylabel_box
label_size = CFG("label_font_size") label_size = CFG("label_font_size")
@@ -91,7 +128,7 @@ def general_background_setup(tup,ymin,ymax,x):
tup[AXIS].set_xlabel(CFG("x_label"), size=label_size, bbox=xlabel_box) tup[AXIS].set_xlabel(CFG("x_label"), size=label_size, bbox=xlabel_box)
tup[AXIS].xaxis.set_label_coords(0.945, 0.03) tup[AXIS].xaxis.set_label_coords(0.945, 0.03)
## GENERAL LEGEND ## ### setup caption ###
legend_handle = tup[AXIS].legend( legend_handle = tup[AXIS].legend(
loc=CFG("legend_location"), loc=CFG("legend_location"),
edgecolor="inherit", edgecolor="inherit",
@@ -100,21 +137,18 @@ def general_background_setup(tup,ymin,ymax,x):
prop={'family': 'monospace','size':CFG("legend_font_size")} prop={'family': 'monospace','size':CFG("legend_font_size")}
) )
legend_handle.get_frame().set_linewidth(0.2) legend_handle.get_frame().set_linewidth(0.2)
#tup[AXIS].set_aspect(get_aspect_ratio(unix_x,ymin,ymax,major_xticks))
def get_aspect_ratio(ux, ymin, ymax, xticks): def get_aspect_ratio(ux, ymin, ymax, xticks):
ratio = 100 ratio = 100
tmp = CFG("aspect_ratio") tmp = CFG("aspect_ratio")
if str(tmp) == "A4": if str(tmp) == "A4":
ratio = a4_aspect() ratio = ( 1/math.sqrt(2) ) * x
else: else:
ratio = tmp ratio = tmp
magic_value = 3.25 magic_value = 3.25 # 2020 sheppy like: ?!??!??
return ratio * ( max(ux) - min(ux) ) / float(ymax - ymin + magic_value) return ratio * ( max(ux) - min(ux) ) / float(ymax - ymin + magic_value)
def a4_aspect(x):
return ( 1/math.sqrt(2) ) * x
def grid(tup, xticks, ymin, ymax): def grid(tup, xticks, ymin, ymax):
lw = CFG("grid_line_width") lw = CFG("grid_line_width")
@@ -154,7 +188,7 @@ def find_step(step,x,total_xticks):
return (start, step) return (start, step)
min_delta_step = timedelta(days=1) # the actual step that has the lowest delta min_delta_step = timedelta(days=1) # the actual step that has the lowest delta
min_delta = timedelta(days=1000) # the delta o thus step min_delta = timedelta(days=1000) # the delta of thus step
for s in intervals: for s in intervals:
delta = max(s, step)-min(s, step) delta = max(s, step)-min(s, step)
if delta < min_delta: if delta < min_delta:
@@ -192,7 +226,8 @@ def parse_possible_intervals():
elif s.endswith("d"): elif s.endswith("d"):
parsed_intervals += [timedelta(days=st)] parsed_intervals += [timedelta(days=st)]
else: else:
raise ValueError("invalide Zeitspezifizierer in %s (muss, s,m,h oder d sein)"%str(intervals)) raise ValueError("Invalide Zeitspezifizierer in %s (muss, s,m,h oder d sein)" % str(intervals))
return parsed_intervals return parsed_intervals
def warn_on_too_much_xticks(x,total_xticks,step): def warn_on_too_much_xticks(x,total_xticks,step):