Repository: bokeh/bokeh

Issue:
`ImageURL.{w,h}` use data units by default
This is broken yet again. `w` and `h` uses `DistanceSpec` which uses `data` units by default. Even help entries for both of those properties say that values are in pixels.


Discussion:
@mattpap I don't see where the help entries say that. I see:
```
    h = DistanceSpec(help="""
    The height of the plot region that the image will occupy.
    .. note::
        This is not the number of pixels that an image is tall.
        That number is fixed by the image itself.
    .. note::
        This may be renamed to "dh" in the future.
    """)
```
Which is only saying that `h` is *not* the natural height of the image, in pixels (the image simply is however tall it is in pixels). The intent with `w` and `h` is to set what size region the image should be scaled to. Why should that not be in data units? If using image URL as a cheap "tile" source data units are in fact what you'd want. I'm not convinced this should be changed or that it isn't correct as is. 
Actually I think what used to happen, and what might be reasonable, is that if `w` and `h` are not specified, then the pixels dimensions of the image are used, and interpreted as data space values. 
ping @bokeh/dev I'd like to propose:
```
h = DistanceSpec(default=None, help="""
    The height of the plot region that the image will occupy in data space.
   
    The default value for this is ``None``, in which case the height of the image (in 
    pixels) will be used as the *data* space height. 
        
    """)
```
This seems reasonable.  

Would this allow for setting the plot region to be square?  This has been something I have wanted to be able to do when plotting geometric shapes/structures (and I'm sure there is an issue for it somewhere).  Simply setting `width` and `height` does not work b/c it does not include the axes (and legend if it is outside).
@StevenCHowell no this is unrelated to fixing the central region plot area aspect, which has as separate issue (https://github.com/bokeh/bokeh/issues/474)

Implementing the idea I suggested above is problematic. I forgot the image (and hence its dimensions) are not immediately available. I think the answer it to keep this a `DataSpec` but change the default units to `screen`. That we can make resonably work with `None` meaning "same units as the image itself" because  the dimension computation can be punted until render time (as it sort of already is)

Resolving patch:
diff --git a/bokeh/models/glyphs.py b/bokeh/models/glyphs.py
--- a/bokeh/models/glyphs.py
+++ b/bokeh/models/glyphs.py
@@ -467,28 +467,18 @@ class ImageURL(Glyph):
     The y-coordinates to locate the image anchors.
     """)
 
-    # TODO: (bev) rename to "dw" for consistency
-    w = DistanceSpec(help="""
-    The widths of the plot regions that the images will occupy.
-
-    .. note::
-        This is not the number of pixels that an image is wide.
-        That number is fixed by the image itself.
+    w = DistanceSpec(default=None, help="""
+    The height of the plot region that the image will occupy in data space.
 
-    .. note::
-        This may be renamed to "dw" in the future.
+    The default value is ``None``, in which case the image will be displayed
+    at its actual image size (regardless of the units specified here).
     """)
 
-    # TODO: (bev) rename to "dh" for consistency
-    h = DistanceSpec(help="""
-    The height of the plot region that the image will occupy.
-
-    .. note::
-        This is not the number of pixels that an image is tall.
-        That number is fixed by the image itself.
+    h = DistanceSpec(default=None, help="""
+    The height of the plot region that the image will occupy in data space.
 
-    .. note::
-        This may be renamed to "dh" in the future.
+    The default value is ``None``, in which case the image will be displayed
+    at its actual image size (regardless of the units specified here).
     """)
 
     angle = AngleSpec(default=0, help="""
diff --git a/examples/models/file/image_url.py b/examples/models/file/image_url.py
--- a/examples/models/file/image_url.py
+++ b/examples/models/file/image_url.py
@@ -34,7 +34,7 @@
 plot.add_glyph(source, image2)
 
 image3 = ImageURL(url=dict(value=url), x=200, y=-100, anchor="bottom_right")
-plot.add_glyph(source, image3)
+plot.add_glyph(image3)
 
 xaxis = LinearAxis()
 plot.add_layout(xaxis, 'below')


Test patch:
diff --git a/bokehjs/test/models/glyphs/image_url.coffee b/bokehjs/test/models/glyphs/image_url.coffee
--- a/bokehjs/test/models/glyphs/image_url.coffee
+++ b/bokehjs/test/models/glyphs/image_url.coffee
@@ -63,3 +63,20 @@ describe "ImageURL module", ->
       image_url_view.map_data()
       expect(image_url_view.sw).to.be.deep.equal([100])
       expect(image_url_view.sh).to.be.deep.equal([200])
+
+    it "`_map_data` should map data to NaN if w and h are null, regardless of units", ->
+      # if sw, sh are NaN, then the image width or height are used during render
+      @image_url.w = null
+      @image_url.h = null
+
+      image_url_view = create_glyph_view(@image_url)
+      image_url_view.map_data()
+      expect(image_url_view.sw).to.be.deep.equal([NaN])
+      expect(image_url_view.sh).to.be.deep.equal([NaN])
+
+      @image_url.properties.w.units = "screen"
+      @image_url.properties.h.units = "screen"
+      image_url_view = create_glyph_view(@image_url)
+      image_url_view.map_data()
+      expect(image_url_view.sw).to.be.deep.equal([NaN])
+      expect(image_url_view.sh).to.be.deep.equal([NaN])