@@ -905,18 +905,27 @@ def axvline(self, x=0, ymin=0, ymax=1, **kwargs):
905905 return l
906906
907907 @docstring .dedent_interpd
908- def axline (self , xy1 , xy2 , ** kwargs ):
908+ def axline (self , xy1 , xy2 = None , * , slope = None , ** kwargs ):
909909 """
910- Add an infinitely long straight line that passes through two points.
910+ Add an infinitely long straight line.
911+
912+ The line can be defined either by two points *xy1* and *xy2*, or
913+ by one point *xy1* and a *slope*.
911914
912915 This draws a straight line "on the screen", regardless of the x and y
913916 scales, and is thus also suitable for drawing exponential decays in
914- semilog plots, power laws in loglog plots, etc.
917+ semilog plots, power laws in loglog plots, etc. However, *slope*
918+ should only be used with linear scales; It has no clear meaning for
919+ all other scales, and thus the behavior is undefined. Please specify
920+ the line using the points *xy1*, *xy2* for non-linear scales.
915921
916922 Parameters
917923 ----------
918924 xy1, xy2 : (float, float)
919925 Points for the line to pass through.
926+ Either *xy2* or *slope* has to be given.
927+ slope : float, optional
928+ The slope of the line. Either *xy2* or *slope* has to be given.
920929
921930 Returns
922931 -------
@@ -941,12 +950,29 @@ def axline(self, xy1, xy2, **kwargs):
941950
942951 >>> axline((0, 0), (1, 1), linewidth=4, color='r')
943952 """
953+ def _to_points (xy1 , xy2 , slope ):
954+ """
955+ Check for a valid combination of input parameters and convert
956+ to two points, if necessary.
957+ """
958+ if (xy2 is None and slope is None or
959+ xy2 is not None and slope is not None ):
960+ raise TypeError (
961+ "Exactly one of 'xy2' and 'slope' must be given" )
962+ if xy2 is None :
963+ x1 , y1 = xy1
964+ xy2 = (x1 , y1 + 1 ) if np .isinf (slope ) else (x1 + 1 , y1 + slope )
965+ return xy1 , xy2
944966
945967 if "transform" in kwargs :
946968 raise TypeError ("'transform' is not allowed as a kwarg; "
947969 "axline generates its own transform" )
948- x1 , y1 = xy1
949- x2 , y2 = xy2
970+ if slope is not None and (self .get_xscale () != 'linear' or
971+ self .get_yscale () != 'linear' ):
972+ raise TypeError ("'slope' cannot be used with non-linear scales" )
973+
974+ datalim = [xy1 ] if xy2 is None else [xy1 , xy2 ]
975+ (x1 , y1 ), (x2 , y2 ) = _to_points (xy1 , xy2 , slope )
950976 line = mlines ._AxLine ([x1 , x2 ], [y1 , y2 ], ** kwargs )
951977 # Like add_line, but correctly handling data limits.
952978 self ._set_artist_props (line )
@@ -956,7 +982,7 @@ def axline(self, xy1, xy2, **kwargs):
956982 line .set_label (f"_line{ len (self .lines )} " )
957983 self .lines .append (line )
958984 line ._remove_method = self .lines .remove
959- self .update_datalim ([ xy1 , xy2 ] )
985+ self .update_datalim (datalim )
960986
961987 self ._request_autoscale_view ()
962988 return line
0 commit comments