Repository: huffmanjohnf/temp-humidity-hexbin

Issue:
Automate Defaults
**What's your idea?**
Automate suggested defaults that are data-driven. Specifically:
 - [x] gridsize
 - [x] graph window


Discussion:

Patch:
diff --git a/temp_humidity_hexbin/visual.py b/temp_humidity_hexbin/visual.py
index a85a92f..79ffb86 100644
--- a/temp_humidity_hexbin/visual.py
+++ b/temp_humidity_hexbin/visual.py
@@ -1,8 +1,46 @@
+from typing import Tuple
+
 import pandas as pd
 import seaborn as sns
 
 
-def hexbin_plt(df: pd.DataFrame, sp_cool: float = 72.0, sp_heat: float = 68.0, sp_humi: float = 55.0):
+def get_range(S: pd.Series):
+    return (S.quantile(0.01), S.quantile(0.99))
+
+
+def find_edge(considerations, how: str = "max", buffer: int = 1):
+    assert how in ["min", "max"]
+    if how == "min":
+        return min(considerations) - buffer
+    else:
+        return max(considerations) + buffer
+
+
+def gridsize(x_01: float, x_99: float, y_01: float, y_99: float, scale: int = 2):
+    xgrid = x_99 - x_01
+    ygrid = y_99 - y_01
+    correction_factor = min([xgrid, ygrid])
+    xgrid = max([int(xgrid * (correction_factor / xgrid) * scale), 1])
+    ygrid = max([int(ygrid * (correction_factor / ygrid) * scale), 1])
+    return (ygrid, xgrid)
+
+
+def hexbin_plt(
+    df: pd.DataFrame,
+    sp_cool: float = 72.0,
+    sp_heat: float = 68.0,
+    sp_humi: float = 55.0,
+    xlim: Tuple[int] = None,
+    ylim: Tuple[int] = None,
+):
+    x_range = get_range(df["Temperature"])
+    y_range = get_range(df["Humidity"])
+
+    if not xlim:
+        xlim = (find_edge([sp_heat, x_range[0]], "min"), find_edge([sp_cool, x_range[1]], "max"))
+    if not ylim:
+        ylim = (y_range[0], find_edge([sp_humi, y_range[1]], "max"))
+
     hexbin = sns.jointplot(
         x="Temperature",
         y="Humidity",
@@ -12,8 +50,9 @@ def hexbin_plt(df: pd.DataFrame, sp_cool: float = 72.0, sp_heat: float = 68.0, s
         ratio=15,
         space=0,
         edgecolor="w",
-        xlim=(64, 76),
-        ylim=(45, 65),
+        xlim=xlim,
+        ylim=ylim,
+        joint_kws=dict(gridsize=gridsize(*x_range, *y_range)),
         color="k",
     )
 


Test patch:
diff --git a/tests/test_visual.py b/tests/test_visual.py
index a954758..55dafc6 100644
--- a/tests/test_visual.py
+++ b/tests/test_visual.py
@@ -4,8 +4,18 @@ from temp_humidity_hexbin.visual import hexbin_plt
 
 
 @pytest.mark.parametrize(
-    "sp_cool, sp_heat, sp_humi",
-    [(72.0, 68.0, 55.0), (76.0, 64.0, 60.0), (72.5, 68.4, 55.6)],
+    "sp_cool, sp_heat, sp_humi, xlim, ylim",
+    [
+        (72.0, 68.0, 55.0, (64, 76), (40, 65)),
+        (76.0, 64.0, 60.0, (63.5, 72.5), (50.5, 60.5)),
+        (72.5, 68.4, 55.6, None, None),
+        (72.0, 68.0, 55.0, None, (45, 65)),
+        (72.0, 68.0, 55.0, None, None),
+    ],
 )
-def test_hexbin_plt(joined_df, sp_cool, sp_heat, sp_humi):
-    _ = hexbin_plt(joined_df, sp_cool, sp_heat, sp_humi)
+def test_hexbin_plt(joined_df, sp_cool, sp_heat, sp_humi, xlim, ylim):
+    _ = hexbin_plt(joined_df, sp_cool, sp_heat, sp_humi, xlim, ylim)
+
+
+def test_all_defaults(joined_df):
+    _ = hexbin_plt(joined_df)