Repository: bokeh/bokeh

Issue:
[BUG] Gridlines are rendered under image plot.
#### ALL software version info (bokeh, python, notebook, OS, browser, any other relevant packages)

```
Python version      :  3.7.3 | packaged by conda-forge | (default, Jul  1 2019, 14:38:56)
IPython version     :  7.8.0
Tornado version     :  5.1.1
Bokeh version       :  1.3.4
BokehJS static path :  /Users/jsignell/hvplot/envs/dev/lib/python3.7/site-packages/bokeh/server/static
node.js version     :  v12.9.1
npm version         :  6.10.3
```

#### Description of expected behavior and the observed behavior
Grid lines are rendered under image rather than on top as expected. This issue first came up in https://github.com/pyviz/hvplot/issues/314 where it was pointed out that matplotlib renders the gridlines on top of the image. I think that should probably be the default behavior for images, but overall gridline z ordering should be configurable.

#### Complete, minimal, self-contained example code that reproduces the issue

```python
import numpy as np
from bokeh.plotting import figure, output_file, show
output_file("gridlines.html")

N = 500
x = np.linspace(0, 10, N)
y = np.linspace(0, 10, N)
xx, yy = np.meshgrid(x, y)
d = np.sin(xx)*np.cos(yy)

p = figure(plot_width=400, plot_height=400)
p.image(image=[d], x=0, y=0, dw=10, dh=10, palette="Spectral11")
show(p)
```

#### Screenshots or screencasts of the bug in action
<img width="408" alt="Screen Shot 2019-09-24 at 11 29 35 AM" src="https://user-images.githubusercontent.com/4806877/65526449-1ee5b080-debf-11e9-93d7-5bd66c826328.png">



Discussion:
This can be specified manually by setting the image render level to `image`. We could consider changing the default render level, but only for 2.0  I think. I have a vague recollection of it being the way it is currently as a result of a previous user request, but I guess there is no satisfying everyone at once. 

I also think it would be helpful to to survey default behavior in more tools than just MPL. 

Edit: yah, just changing the order and nothing else gives pretty terrible results:

```
r = p.image(image=[d], x=0, y=0, dw=10, dh=10, palette="Spectral11")
r.level = 'image'
```
<img width="414" alt="Screen Shot 2019-09-24 at 8 48 01 AM" src="https://user-images.githubusercontent.com/1078448/65527784-19c93700-dea8-11e9-84d7-54fea994e996.png">

Somewhat better with
```
p.grid.grid_line_width=0.5
p.grid.grid_line_alpha=0.8
```

<img width="410" alt="Screen Shot 2019-09-24 at 8 54 01 AM" src="https://user-images.githubusercontent.com/1078448/65528273-e89d3680-dea8-11e9-85a3-01c223fd8e3c.png">

@bryevdv I was the one that came up with the issue in the first place. I agree, there's no pleasing everyone at once. However, I think the current behavior of the grid objectively doesn't serve any purpose. Looking at @jsignell 's plot, having the grid there makes no different *at all* for the plot. It doesn't add any information.

In your example you can argue that the plot looks bad/good, but the grid objective adds information, since now I can more easily find coordinates once I find some feature on the plot I'm interested in.

This is just my opinion, of course, but I've been making scientific plots almost daily for the past 10 years or so, so I say this based on my personal experience.
@tomchor I'm aware of the reason gridlines over the images are desirable. I am not saying nothing should be done, I am saying that whatever is done needs to take lots of things in to consideration:

* The current defaults use way too much "ink" when they are on top of images
* Is applying an alpha to grid lines reasonable to do? Or does that yield an unfaithful representation?
* What about fractional line widths? At that point the browser is anti-aliasing. Same question about fidelity. 
* Assuming one or both of those is OK, is there a default that will work in all the other cases when there *aren't* images? Or will the grid be too faint to be useful in other cases?
* If so, do we consider some complicated scheme to condition the default on the presence or absence of images? Tehcnically a pain, and likely surprising to users. 

At the end of the day, since there is truly no satisfying eery user or use case simultaneously, we have tried to make Bokeh highly configurable, so that at the end of the day, users can always solve these issues on their own if need be (as I have shown above)
@bryevdv I apologize, I may missed the point of your first answer. I don't know much about the technicalities of Bokeh since I've only ever used it through `hvplot`, but I'll try to into translating your re-ordering workaround (which looks good to me) into something that I can do with `hvplot` (assuming it's possible).
@tomchor no apology necessary. It's certainly possible to set all those values on hvplot output but the HV devs will be able to better answer how to do that. 
All that said if we are going to make changes, they should happen for 2.0, so I have added this to that milestone. 

@jsignell do you have any thoughts about this?
This is clearly a change to current behavior, so I think it belongs in 2.0 if it is done at all. 

I looked at altair, ggplot2, and plotly and is seems that they all put the grid under by default, but have it be configurable. So maybe no change is needed as long as there are docs for how to change the level.

Given common precedent in other libraries, I agree this is a docs issue. 

Resolving patch:
diff --git a/examples/plotting/file/image.py b/examples/plotting/file/image.py
--- a/examples/plotting/file/image.py
+++ b/examples/plotting/file/image.py
@@ -12,8 +12,9 @@
 p.x_range.range_padding = p.y_range.range_padding = 0
 
 # must give a vector of image data for image parameter
-p.image(image=[d], x=0, y=0, dw=10, dh=10, palette="Spectral11")
+p.image(image=[d], x=0, y=0, dw=10, dh=10, palette="Spectral11", level="image")
+p.grid.grid_line_width = 0.5
 
 output_file("image.html", title="image.py example")
 
-show(p)  # open a browser
+show(p)
diff --git a/sphinx/source/docs/user_guide/examples/plotting_image.py b/sphinx/source/docs/user_guide/examples/plotting_image.py
--- a/sphinx/source/docs/user_guide/examples/plotting_image.py
+++ b/sphinx/source/docs/user_guide/examples/plotting_image.py
@@ -1,22 +1,17 @@
 import numpy as np
+from bokeh.plotting import figure, show, output_file
 
-from bokeh.plotting import figure, output_file, show
+output_file("image.html", title="image.py example")
 
-# create an array of RGBA data
-N = 20
-img = np.empty((N, N), dtype=np.uint32)
-view = img.view(dtype=np.uint8).reshape((N, N, 4))
-for i in range(N):
-    for j in range(N):
-        view[i, j, 0] = int(255 * i / N)
-        view[i, j, 1] = 158
-        view[i, j, 2] = int(255 * j / N)
-        view[i, j, 3] = 255
+x = np.linspace(0, 10, 250)
+y = np.linspace(0, 10, 250)
+xx, yy = np.meshgrid(x, y)
+d = np.sin(xx)*np.cos(yy)
 
-output_file("image_rgba.html")
+p = figure(plot_width=400, plot_height=400)
+p.x_range.range_padding = p.y_range.range_padding = 0
 
-p = figure(plot_width=400, plot_height=400, x_range=(0, 10), y_range=(0, 10))
-
-p.image_rgba(image=[img], x=[0], y=[0], dw=[10], dh=[10])
+p.image(image=[d], x=0, y=0, dw=10, dh=10, palette="Spectral11", level="image")
+p.grid.grid_line_width = 0.5
 
 show(p)
diff --git a/sphinx/source/docs/user_guide/examples/plotting_image_rgba.py b/sphinx/source/docs/user_guide/examples/plotting_image_rgba.py
new file mode 100644
--- /dev/null
+++ b/sphinx/source/docs/user_guide/examples/plotting_image_rgba.py
@@ -0,0 +1,22 @@
+import numpy as np
+
+from bokeh.plotting import figure, output_file, show
+
+# create an array of RGBA data
+N = 20
+img = np.empty((N, N), dtype=np.uint32)
+view = img.view(dtype=np.uint8).reshape((N, N, 4))
+for i in range(N):
+    for j in range(N):
+        view[i, j, 0] = int(255 * i / N)
+        view[i, j, 1] = 158
+        view[i, j, 2] = int(255 * j / N)
+        view[i, j, 3] = 255
+
+output_file("image_rgba.html")
+
+p = figure(plot_width=400, plot_height=400, x_range=(0, 10), y_range=(0, 10))
+
+p.image_rgba(image=[img], x=[0], y=[0], dw=[10], dh=[10])
+
+show(p)


Test patch:
diff --git a/tests/baselines/sphinx/source/docs/user_guide/examples/plotting_image_rgba b/tests/baselines/sphinx/source/docs/user_guide/examples/plotting_image_rgba
new file mode 100644
--- /dev/null
+++ b/tests/baselines/sphinx/source/docs/user_guide/examples/plotting_image_rgba
@@ -0,0 +1,5 @@
+Plot bbox=[0, 0, 400, 400]
+  LinearAxis bbox=[24, 376, 346, 24]
+  LinearAxis bbox=[0, 5, 24, 371]
+  Title bbox=[24, 5, 346, 0]
+  ToolbarPanel bbox=[370, 5, 30, 371]