Repository: holoviz/holoviews

Issue:
aspect=equal does not match data_aspect=1
<img width="1021" alt="Screen Shot 2019-08-02 at 10 49 14 AM" src="https://user-images.githubusercontent.com/4806877/62378617-33d34280-b513-11e9-97c5-441c8ba46782.png">



Discussion:

Resolving patch:
diff --git a/holoviews/plotting/bokeh/element.py b/holoviews/plotting/bokeh/element.py
--- a/holoviews/plotting/bokeh/element.py
+++ b/holoviews/plotting/bokeh/element.py
@@ -786,7 +786,7 @@ def _update_ranges(self, element, ranges):
             xspan = r-l if util.is_number(l) and util.is_number(r) else None
             yspan = t-b if util.is_number(b) and util.is_number(t) else None
 
-            if self.drawn or (self.aspect != 'equal' and fixed_width and fixed_height):
+            if self.drawn or (fixed_width and fixed_height):
                 # After initial draw or if aspect is explicit
                 # adjust range to match the plot dimension aspect
                 ratio = self.data_aspect or 1
@@ -795,12 +795,13 @@ def _update_ranges(self, element, ranges):
                 elif self.aspect and self.aspect != 'equal':
                     frame_aspect = self.aspect
                 else:
-                    frame_aspect = plot.frame_width/plot.frame_height
+                    frame_aspect = plot.frame_height/plot.frame_width
 
-                desired_xspan = yspan*1./(ratio/frame_aspect)
-                desired_yspan = (xspan*(ratio/frame_aspect))
-                if (np.allclose(desired_xspan, xspan, rtol=0.01) and
-                    np.allclose(desired_yspan, yspan, rtol=0.01)):
+                desired_xspan = yspan*(ratio/frame_aspect)
+                desired_yspan = xspan/(ratio/frame_aspect)
+                if ((np.allclose(desired_xspan, xspan, rtol=0.01) and
+                     np.allclose(desired_yspan, yspan, rtol=0.01)) or
+                    not (util.isfinite(xspan) and util.isfinite(yspan))):
                     pass
                 elif desired_yspan >= yspan:
                     ypad = (desired_yspan-yspan)/2.
diff --git a/holoviews/plotting/bokeh/util.py b/holoviews/plotting/bokeh/util.py
--- a/holoviews/plotting/bokeh/util.py
+++ b/holoviews/plotting/bokeh/util.py
@@ -251,18 +251,21 @@ def compute_layout_properties(
                 else:
                     sizing_mode = 'stretch_both'
 
+
     if fixed_aspect:
+        if ((explicit_width and not frame_width) != (explicit_height and not frame_height)) and logger:
+            logger.warning('Due to internal constraints, when aspect and '
+                           'width/height is set, the bokeh backend uses '
+                           'those values as frame_width/frame_height instead. '
+                           'This ensures the aspect is respected, but means '
+                           'that the plot might be slightly larger than '
+                           'anticipated. Set the frame_width/frame_height '
+                           'explicitly to suppress this warning.')
+
         aspect_type = 'data_aspect' if data_aspect else 'aspect'
         if fixed_width and fixed_height and aspect:
             if aspect == 'equal':
-                data_aspect = None
-                if logger:
-                    logger.warning(
-                        "%s value was ignored because absolute width and "
-                        "height values were provided. To set the scaling "
-                        "between the x- and y-axis independent of the "
-                        "width and height values set the data_aspect."
-                        % aspect_type)
+                data_aspect = 1
             elif not data_aspect:
                 aspect = None
                 if logger:
@@ -291,7 +294,6 @@ def compute_layout_properties(
         elif responsive == 'height':
             sizing_mode = 'scale_height'
 
-
     if responsive == 'width' and fixed_width:
         responsive = False
         if logger:


Test patch:
diff --git a/holoviews/tests/plotting/bokeh/testelementplot.py b/holoviews/tests/plotting/bokeh/testelementplot.py
--- a/holoviews/tests/plotting/bokeh/testelementplot.py
+++ b/holoviews/tests/plotting/bokeh/testelementplot.py
@@ -493,10 +493,10 @@ def test_element_data_aspect_width_height(self):
         self.assertEqual(plot.state.plot_height, 400)
         self.assertEqual(plot.state.plot_width, 400)
         self.assertEqual(plot.state.aspect_scale, 2)
-        self.assertEqual(x_range.start, 0)
-        self.assertEqual(x_range.end, 2)
-        self.assertEqual(y_range.start, -0.5)
-        self.assertEqual(y_range.end, 3.5)
+        self.assertEqual(x_range.start, -2)
+        self.assertEqual(x_range.end, 4)
+        self.assertEqual(y_range.start, 0)
+        self.assertEqual(y_range.end, 3)
 
     def test_element_data_aspect_frame_width(self):
         curve = Curve([1, 2, 3]).opts(data_aspect=2, frame_width=400)