plot_utils: make xlim and ylim consistent and accept strings as well as tuples
before xlim = None was different than ylim = None. Discard the None
and just make them accept strings that describe their purpose.
diff --git a/cr2/plot_utils.py b/cr2/plot_utils.py
index 45a9606..ec8ef15 100644
--- a/cr2/plot_utils.py
+++ b/cr2/plot_utils.py
@@ -33,11 +33,44 @@
return title
+def set_lim(lim, get_lim, set_lim):
+ """Set x or y limitis of the plot
+
+ lim can be a tuple containing the limits or the string "default"
+ or "range". "default" does nothing and uses matplotlib default.
+ "range" extends the current margin by 10%. This is useful since
+ the default xlim and ylim of the plots sometimes make it harder to
+ see data that is just in the margin.
+
+ """
+ if lim == "default":
+ return
+
+ if lim == "range":
+ cur_lim = get_lim()
+ lim = (cur_lim[0] - 0.1 * (cur_lim[1] - cur_lim[0]),
+ cur_lim[1] + 0.1 * (cur_lim[1] - cur_lim[0]))
+
+ set_lim(lim[0], lim[1])
+
+def set_xlim(ax, xlim):
+ """Set the xlim of the plot
+
+ See set_lim() for the details
+ """
+ set_lim(xlim, ax.get_xlim, ax.set_xlim)
+
+def set_ylim(ax, ylim):
+ """Set the ylim of the plot
+
+ See set_lim() for the details
+ """
+ set_lim(ylim, ax.get_ylim, ax.set_ylim)
+
def pre_plot_setup(width=None, height=None):
"""initialize a figure
- width and height are numbers, ylim is a tuple with min and max
- values for the y axis. This function should be called before
+ width and height are numbers This function should be called before
any calls to plot()
"""
@@ -47,10 +80,13 @@
return ax
-def post_plot_setup(ax, title="", xlabel=None, xlim=None, ylim=None):
+def post_plot_setup(ax, title="", xlabel=None, xlim="default", ylim="range"):
"""Set xlabel, title, xlim adn ylim of the plot
- This has to be called after calls to .plot()
+ This has to be called after calls to .plot(). The default ylim is
+ to extend it by 10% because matplotlib default makes it hard
+ values that are close to the margins
+
"""
if xlabel is None:
@@ -60,15 +96,8 @@
if title:
plt.title(title)
- if not ylim:
- cur_ylim = ax.get_ylim()
- ylim = (cur_ylim[0] - 0.1 * (cur_ylim[1] - cur_ylim[0]),
- cur_ylim[1] + 0.1 * (cur_ylim[1] - cur_ylim[0]))
-
- ax.set_ylim(ylim[0], ylim[1])
-
- if xlim:
- ax.set_xlim(xlim[0], xlim[1])
+ set_ylim(ax, ylim)
+ set_xlim(ax, xlim)
def plot_allfreqs(in_power, out_power, map_label, title="", width=None, height=None):
"""Do allfreqs plots similar to those of CompareRuns"""
diff --git a/cr2/thermal.py b/cr2/thermal.py
index 684bf7a..42af452 100644
--- a/cr2/thermal.py
+++ b/cr2/thermal.py
@@ -120,7 +120,7 @@
unique_word="thermal_zone=",
)
- def plot_temperature(self, title="", width=None, height=None, ylim=None):
+ def plot_temperature(self, title="", width=None, height=None, ylim="range"):
"""Plot the temperature"""
dfr = self.get_data_frame()
title = normalize_title("Temperature", title)
@@ -147,7 +147,7 @@
with open("thermal.csv", "w") as fout:
fout.write(self.data_csv)
- def plot_temperature(self, title="", width=None, height=None, ylim=None):
+ def plot_temperature(self, title="", width=None, height=None, ylim="range"):
"""Plot the temperature"""
dfr = self.get_data_frame()
control_temp_series = (dfr["currT"] + dfr["deltaT"]) / 1000
diff --git a/tests/test_plot_utils.py b/tests/test_plot_utils.py
index d774118..361477c 100644
--- a/tests/test_plot_utils.py
+++ b/tests/test_plot_utils.py
@@ -19,6 +19,51 @@
self.assertEquals(plot_utils.normalize_title("Foo", ""), "Foo")
self.assertEquals(plot_utils.normalize_title("Foo", "Bar"), "Bar - Foo")
+ def test_set_lim(self):
+ """Test set_lim()"""
+
+ class GetSet(object):
+ def __init__(self):
+ self.min = 1
+ self.max = 2
+
+ def get(self):
+ return (self.min, self.max)
+
+ def set(self, minimum, maximum):
+ self.min = minimum
+ self.max = maximum
+
+ gs = GetSet()
+
+ plot_utils.set_lim("default", gs.get, gs.set)
+ self.assertEquals(gs.min, 1)
+ self.assertEquals(gs.max, 2)
+
+ plot_utils.set_lim("range", gs.get, gs.set)
+ self.assertEquals(gs.min, 0.9)
+ self.assertEquals(gs.max, 2.1)
+
+ plot_utils.set_lim((0, 100), gs.get, gs.set)
+ self.assertEquals(gs.min, 0)
+ self.assertEquals(gs.max, 100)
+
+ def test_set_ylim(self):
+ """Test that set_ylim() doesn't bomb"""
+
+ ax = plot_utils.pre_plot_setup()
+
+ plot_utils.set_ylim(ax, "default")
+ plot_utils.set_ylim(ax, (0, 5))
+
+ def test_set_xlim(self):
+ """Test that set_xlim() doesn't bomb"""
+
+ ax = plot_utils.pre_plot_setup()
+
+ plot_utils.set_xlim(ax, "default")
+ plot_utils.set_xlim(ax, (0, 5))
+
def test_post_plot_setup(self):
"""Test that post_plot_setup() doesn't bomb"""
@@ -27,8 +72,10 @@
plot_utils.post_plot_setup(ax)
plot_utils.post_plot_setup(ax, title="Foo")
plot_utils.post_plot_setup(ax, ylim=(0, 72))
+ plot_utils.post_plot_setup(ax, ylim="range")
plot_utils.post_plot_setup(ax, xlabel="Bar")
plot_utils.post_plot_setup(ax, xlim=(0, 100))
+ plot_utils.post_plot_setup(ax, xlim="default")
class TestPlotUtilsNeedTrace(TestThermalBase):
def test_plot_allfreqs(self):