diff --git a/critdd/tikz.py b/critdd/tikz.py index db46703..157c3f7 100644 --- a/critdd/tikz.py +++ b/critdd/tikz.py @@ -30,6 +30,12 @@ def __init__(self, path): "title style": "yshift=\\baselineskip", } +def _merge_dicts(a, b): + """Merge two dictionaries in the same way that `a | b` does since Python 3.9.""" + a = { k: a[k] for k in a } # create a copy of dict a + a.update(b) # merge dicts a and b + return a + def to_file(path, tikz_code): """Export the tikz_code to a file.""" root, ext = os.path.splitext(path) @@ -68,18 +74,18 @@ def requires_document(path): def to_str(average_ranks, groups, treatment_names, *, reverse_x=False, as_document=False, tikzpicture_options=dict(), axis_options=dict(), preamble=None, title=None): """Return a string with Tikz code.""" if title is not None: - axis_options |= {"title": title} # set the title + axis_options = _merge_dicts(axis_options, {"title": title}) # set the title warnings.warn( "to_str(..., title=x) will be retired in v0.1, please use to_str(..., axis_options={\"title\": title}) instead.", DeprecationWarning ) k = len(average_ranks) changepoint = int(np.floor(k/2)) # index for breaking left and right treatments - axis_defaults = AXIS_OPTIONS | { # diagram-dependent axis options + axis_defaults = _merge_dicts(AXIS_OPTIONS, { # diagram-dependent axis options "xmax": str(k), "ymin": str(-(changepoint+1.5)), "height": f"{changepoint+2}\\baselineskip", # ceil(k/2) + 1 extra \\baselikeskip - } + }) if k <= 8: axis_defaults["xtick"] = ",".join((np.arange(k)+1).astype(str)) if k <= 6: @@ -136,8 +142,8 @@ def to_str(average_ranks, groups, treatment_names, *, reverse_x=False, as_docume y_group_pos[i] )) tikz_str = _tikzpicture( - _axis(*commands, options=axis_defaults | axis_options), - options = TIKZPICTURE_OPTIONS | tikzpicture_options + _axis(*commands, options=_merge_dicts(axis_defaults, axis_options)), + options = _merge_dicts(TIKZPICTURE_OPTIONS, tikzpicture_options) ) if as_document: tikz_str = _document(tikz_str, preamble=preamble) diff --git a/critdd/tikz_2d.py b/critdd/tikz_2d.py index 5fd17c5..eafc4cc 100644 --- a/critdd/tikz_2d.py +++ b/critdd/tikz_2d.py @@ -27,13 +27,13 @@ def to_str(average_ranks, groups, treatment_names, diagram_names, *, reverse_x=F """Return a string with Tikz code.""" m, k = average_ranks.shape # numbers of diagrams and treatments changepoint = int(np.floor(k/2)) # index for breaking left and right treatments - axis_defaults = AXIS_OPTIONS | { # diagram-dependent axis options + axis_defaults = tikz._merge_dicts(AXIS_OPTIONS, { # diagram-dependent axis options "ytick": ",".join((np.arange(m)+1).astype(str)), "yticklabels": ",".join([ "{" + tikz._label(n) + "}" for n in diagram_names ]), "xmax": str(k + .5), "ymax": str(m + .66), "height": f"{.5 if m == 2 else m/5 if m < 5 else m/6}*\\axisdefaultheight", - } + }) if reverse_x: axis_defaults["x dir"] = "reverse" commands = [ _rank_plot(average_ranks[:,i], treatment_names[i]) for i in range(k) ] @@ -45,8 +45,8 @@ def to_str(average_ranks, groups, treatment_names, diagram_names, *, reverse_x=F i + (j+.66) / (1.33 * len(groups[i]) + 1) + 1 )) tikz_str = tikz._tikzpicture( - tikz._axis(*commands, options=axis_defaults | axis_options), - options = TIKZPICTURE_OPTIONS | tikzpicture_options + tikz._axis(*commands, options=tikz._merge_dicts(axis_defaults, axis_options)), + options = tikz._merge_dicts(TIKZPICTURE_OPTIONS, tikzpicture_options) ) if as_document: tikz_str = tikz._document(tikz_str, preamble=preamble)