From 1c90a4c4b6fd2f57d9a1b6e3757007b1ae8ae31a Mon Sep 17 00:00:00 2001 From: Cal Wing <20716204+calw20@users.noreply.github.com> Date: Sun, 25 Aug 2024 23:27:14 +1000 Subject: [PATCH] Bump makeGraph to V1.10.0 --- makeGraph.py | 82 ++++++++++++++++++++++++++++++++++++----------- requirements.txt | Bin 88 -> 84 bytes 2 files changed, 64 insertions(+), 18 deletions(-) diff --git a/makeGraph.py b/makeGraph.py index d515049..1a843c8 100644 --- a/makeGraph.py +++ b/makeGraph.py @@ -6,7 +6,7 @@ #### 2023 - Added UQ Default Colours to MatPlotLib __author__ = "Cal Wing" -__version__ = "0.1.9" +__version__ = "0.1.10" from collections.abc import Iterator import numpy as np @@ -190,7 +190,7 @@ def colorbar(mappable, size="5%", pad=0.05, lsize=None, lpad=None, lax=True, **k ## Make Graph Function -def makeGraph(graphData, showPlot=True, doProgramBlock=True, figSavePath=None) -> tuple[matplotlib.figure.Figure, tuple[matplotlib.axes.Axes, ...]]: +def makeGraph(graphData, showPlot=True, doProgramBlock=True, figSavePath=None, hideEmptyAxis=False) -> tuple[matplotlib.figure.Figure, tuple[matplotlib.axes.Axes, ...]]: """ Generate a matplotlib graph based on a simple dictionary object Input: dict(graphData): The dictionary containing all the graph data - see example for more info @@ -242,7 +242,8 @@ def makeGraph(graphData, showPlot=True, doProgramBlock=True, figSavePath=None) - loopKeys = [ "xLabel", "yLabel", "title", "axis", "grid", "xPos", "yPos", "xLabelPos", "yLabelPos", "xTickPos", "yTickPos", "xScale", "yScale", - "xTickMap", "yTickMap", "plots", "xLim", "yLim" + "xTickMap", "yTickMap", "plots", "xLim", "yLim", "ledgLoc", "y2Label", + "ticklabel" ] #Feel like this could be optimized @@ -256,7 +257,15 @@ def makeGraph(graphData, showPlot=True, doProgramBlock=True, figSavePath=None) - for i, axGraphData in enumerate(graphData["subPlots"]): - ax = flatAxes[i] + ax1 = flatAxes[i] + + if bool(sum([("y2" in pData) for pData in axGraphData["plots"]])): + ax2 = ax1.twinx() + else: + ax2 = None + + # Duct Tape + ax = ax1 #Draw many plots as needed # Also provide functions for drawing other types of lines @@ -267,28 +276,38 @@ def makeGraph(graphData, showPlot=True, doProgramBlock=True, figSavePath=None) - getSafeColour = getSafeValue("colour") or getSafeValue("color") #Frigen American Spelling optArgs = getSafeValue("args", {}) #Allow for other args to be passed in + if "x" in pData: + xData = pData["x"] + + if "y" in pData: + yData = pData["y"] + elif "y2" in pData: + yData = pData["y2"] + ax = ax2 + if "type" not in pData or pData["type"] == "plot": - ax.plot(pData["x"], pData["y"], label=getSafeValue("label"), color=getSafeColour, **optArgs) + ax.plot(xData, yData, label=getSafeValue("label"), color=getSafeColour, **optArgs) elif pData["type"] == "point": - ax.scatter(pData["x"], pData["y"], + ax.scatter(xData, yData, marker=getSafeValue("marker"), label=getSafeValue("label"), color=getSafeColour, zorder=getSafeValue("zorder", 2), **optArgs ) elif pData["type"] == "hLine": - ax.hlines(pData["y"], *pData["x"], label=getSafeValue("label"), color=getSafeColour, **optArgs) + ax.hlines(yData, *xData, label=getSafeValue("label"), color=getSafeColour, **optArgs) elif pData["type"] == "vLine": - ax.vlines(pData["x"], *pData["y"], label=getSafeValue("label"), color=getSafeColour, **optArgs) + ax.vlines(xData, *yData, label=getSafeValue("label"), color=getSafeColour, **optArgs) elif pData["type"] == "axvLine": - if "y" not in pData: pData["y"] = (0, 1) #Span the whole graph - ax.axvline(pData["x"], *pData["y"], label=getSafeValue("label"), color=getSafeColour, **optArgs) + if "y" not in pData: yData = (0, 1) #Span the whole graph + ax.axvline(xData, *yData, label=getSafeValue("label"), color=getSafeColour, **optArgs) elif pData["type"] == "axhLine": - if "x" not in pData: pData["x"] = (0, 1) #Span the whole graph - ax.axhline(pData["y"], *pData["x"], label=getSafeValue("label"), color=getSafeColour, **optArgs) + if "x" not in pData: xData = (0, 1) #Span the whole graph + ax.axhline(yData, *xData, label=getSafeValue("label"), color=getSafeColour, **optArgs) + elif pData["type"] == "scatter": + ax.scatter(xData, yData, marker=getSafeValue("marker"), label=getSafeValue("label"), color=getSafeColour, **optArgs) + elif pData["type"] == "contour": cs = ax.contour(getSafeValue("x"), getSafeValue("y"), pData["z"], levels=getSafeValue("levels"), colors=getSafeColour, **optArgs) if "label" in pData: cs.collections[0].set_label(getSafeValue("label")) - elif pData["type"] == "scatter": - ax.scatter(pData["x"], pData["y"], marker=getSafeValue("marker"), label=getSafeValue("label"), color=getSafeColour, **optArgs) elif pData["type"] == "matshow": ms = ax.matshow(pData["matrix"], origin=getSafeValue("origin"), label=getSafeValue("label"), **optArgs) if "colourBar" in pData: @@ -296,9 +315,9 @@ def makeGraph(graphData, showPlot=True, doProgramBlock=True, figSavePath=None) - elif pData["type"] == "pColourMesh": mesh = [] if "X" in pData or "Y" in pData: - mesh = [pData["X"], pData["Y"], pData["Z"]] + mesh = [xData, yData, pData["Z"]] if "x" in pData or "y" in pData: - x = pData["x"]; y = pData["y"] + x = xData; y = yData if type(x) in [int, float]: x = (0, x, None) if type(y) in [int, float]: y = (0, x, None) @@ -352,8 +371,10 @@ def makeGraph(graphData, showPlot=True, doProgramBlock=True, figSavePath=None) - #Set extra options as needed + ax = ax1 if "xLabel" in axGraphData: ax.set_xlabel(axGraphData["xLabel"]) # Add an x-label to the axes. if "yLabel" in axGraphData: ax.set_ylabel(axGraphData["yLabel"]) # Add an y-label to the axes. + if "y2Label" in axGraphData: ax2.set_ylabel(axGraphData["y2Label"]) # Add a y2-label to the axes. if "title" in axGraphData: ax.set_title(axGraphData["title"]) # Add an title to the axes. if "axis" in axGraphData: ax.axis(axGraphData["axis"]) # Set the axis type if "grid" in axGraphData: ax.grid(axGraphData["grid"]) # Add grids to the graph @@ -389,8 +410,29 @@ def makeGraph(graphData, showPlot=True, doProgramBlock=True, figSavePath=None) - if "yTickMap" in axGraphData: #Allow for the mapping / transformation of the yAxis Ticks yTicks = matplotlib.ticker.FuncFormatter(lambda y, pos: '{0:g}'.format(axGraphData["yTickMap"](y))) ax.yaxis.set_major_formatter(yTicks) + if "plots" in axGraphData and bool(sum([("label" in pData) for pData in axGraphData["plots"]])): - ax.legend() #Only draw the legend if there are any defined + locPoint = axGraphData["ledgLoc"] if "ledgLoc" in axGraphData else None + lines1, labels1 = ax1.get_legend_handles_labels() + + if ax2: + lines2, labels2 = ax2.get_legend_handles_labels() + ax2.legend(lines1 + lines2, labels1 + labels2, loc=locPoint) + else: + ax1.legend(lines1, labels1, loc=locPoint) + + if "ticklabel" in axGraphData: + style = axGraphData["ticklabel"]["style"] if "style" in axGraphData["ticklabel"] else "" + axis = axGraphData["ticklabel"]["axis"] if "axis" in axGraphData["ticklabel"] else "both" + limits = axGraphData["ticklabel"]["limits"] if "limits" in axGraphData["ticklabel"] else None + optArgs = axGraphData["ticklabel"]["optArgs"] if "optArgs" in axGraphData["ticklabel"] else {} + ax.ticklabel_format(axis=axis, style=style, scilimits=limits, **optArgs) + + #Should work? + if hideEmptyAxis: + if not ax.collections and not ax.lines: + ax.set_axis_off() + if "title" in graphData and not "figTitle" in graphData: fig.canvas.manager.set_window_title(graphData["title"].replace("\n", " ")) #Set the figure title correctly if "figTitle" in graphData: @@ -400,7 +442,11 @@ def makeGraph(graphData, showPlot=True, doProgramBlock=True, figSavePath=None) - fig.canvas.manager.set_window_title(graphData["figTitle"].replace("\n", " ")) fig.tight_layout() #Fix labels being cut off sometimes - + + #Very big hack + if hideEmptyAxis: + flatAxes[-1].set_axis_off() + if figSavePath: fig.savefig(figSavePath) diff --git a/requirements.txt b/requirements.txt index d7e824abc16651c2d4d7fe0eddc29f12a7b3a801..f378c6e897f808acbedebe8bb3e6f7dba419bca4 100644 GIT binary patch delta 33 lcmazDnP4GP%#h5G$xy&h$-v9N1*8)h@)%NpWHEyR0|0!d24?^O delta 37 pcmWHEm|&rx%uvjb%#g`Yz);D+%fQ8;3}huT