Repository: bokeh/bokeh

Issue:
Support line annotations like span but with slope
In addition to the vertical and horizontal spans annotations, it would be nice to have a line annotation that can be sloped and can be specified by a point and a slope (or maybe optionally two sets of points which might be more useful if an axis is categorical), where the line does not terminate but continues across the extent of the canvas.

The reason for this request is that it is often desired to place a reference line or a fitted regression line that is not horizontal or vertical, and it is desired for this line to continue beyond the span of the data, or the span of the data is not known at the time of specifying the line, or it is not convenient to specify the line in terms of points to connect at the extent of the data. Especially in the case of superposing a linear regression line, a reference line is easiest specified by a y-intercept and a slope.


Discussion:
This seems reasonable and simple, @hafen would you want to try and submit the PR with some guidance?
If you're ok w/ specifying a line via two sets of (x,y) pairs, it'd be possible to do so with an Arrow annotation with the arrow heads set to ``None``. Obviously, that doesn't accomodate your intercept/slope proposal though.
I think this merits it's own annotation, both because of the different interface but also because of the unbounded behavior 
Yikes I let this one go. @bryevdv do you mean to submit an empty PR with guidance?
I meant would you want to try and develop the PR if we are available to answer questions and provide technical direction?

Resolving patch:
diff --git a/bokeh/models/annotations.py b/bokeh/models/annotations.py
--- a/bokeh/models/annotations.py
+++ b/bokeh/models/annotations.py
@@ -814,6 +814,33 @@ class PolyAnnotation(Annotation):
 
     fill_color = Override(default="#fff9ba")
 
+class Slope(Annotation):
+    """ Render a sloped line as an annotation.
+
+    """
+
+    gradient = Float(help="""
+    The gradient of the line, in data units
+    """)
+
+    y_intercept = Float(help="""
+    The y intercept of the line, in data units
+    """)
+
+    x_range_name = String('default', help="""
+    A particular (named) x-range to use for computing screen locations when
+    rendering annotations on the plot. If unset, use the default x-range.
+    """)
+
+    y_range_name = String('default', help="""
+    A particular (named) y-range to use for computing screen locations when
+    rendering annotations on the plot. If unset, use the default y-range.
+    """)
+
+    line_props = Include(LineProps, use_prefix=False, help="""
+    The %s values for the line.
+    """)
+
 class Span(Annotation):
     """ Render a horizontal or vertical line span.
 
diff --git a/sphinx/source/docs/user_guide/examples/plotting_slope.py b/sphinx/source/docs/user_guide/examples/plotting_slope.py
new file mode 100644
--- /dev/null
+++ b/sphinx/source/docs/user_guide/examples/plotting_slope.py
@@ -0,0 +1,28 @@
+import numpy as np
+
+from bokeh.plotting import figure, show, output_file
+from bokeh.models import Slope
+
+output_file("slope.html", title="slope.py example")
+
+# linear equation parameters
+gradient = 2
+y_intercept = 10
+
+# create random data
+xpts = np.arange(0, 20)
+ypts = gradient * xpts + y_intercept + np.random.normal(0, 4, 20)
+
+p = figure(plot_width=450, plot_height=450, y_range=(0, 1.1 * max(ypts)))
+
+p.circle(xpts, ypts, size=5, color="skyblue")
+
+slope = Slope(gradient=gradient, y_intercept=y_intercept,
+              line_color='orange', line_dash='dashed', line_width=3.5)
+
+p.add_layout(slope)
+
+p.yaxis.axis_label = 'y'
+p.xaxis.axis_label = 'x'
+
+show(p)


Test patch:
diff --git a/bokeh/models/tests/test_annotations.py b/bokeh/models/tests/test_annotations.py
--- a/bokeh/models/tests/test_annotations.py
+++ b/bokeh/models/tests/test_annotations.py
@@ -5,7 +5,7 @@
 from bokeh.core.validation import check_integrity
 from bokeh.models.annotations import (
     Legend, LegendItem, ColorBar, Arrow, BoxAnnotation, Span, LabelSet, Label,
-    Title, Band, Whisker
+    Title, Band, Whisker, Slope
 )
 from bokeh.models import (
     ColumnDataSource, ArrowHead, BasicTicker, BasicTickFormatter, GlyphRenderer
@@ -297,6 +297,25 @@ def test_LabelSet():
         prefix('border_', LINE),
         prefix('background_', FILL))
 
+def test_Slope():
+    slope = Slope()
+    assert slope.plot is None
+    assert slope.gradient is None
+    assert slope.y_intercept is None
+    assert slope.x_range_name == 'default'
+    assert slope.y_range_name == 'default'
+    assert slope.level == 'annotation'
+    check_line_properties(slope, "", 'black', 1.0)
+    check_properties_existence(slope, [
+        "plot",
+        "visible",
+        "gradient",
+        "y_intercept",
+        "x_range_name",
+        "y_range_name",
+        "level",
+    ], LINE)
+
 
 def test_Span():
     line = Span()