@@ -1185,6 +1185,14 @@ def _add_annotation_like(
1185
1185
xref , yref = xaxis .replace ("axis" , "" ), yaxis .replace ("axis" , "" )
1186
1186
new_obj .update (xref = xref , yref = yref )
1187
1187
1188
+ # xref and yref are set to the first axes if not set.
1189
+ # This is so that routines that need these to be specified if row and
1190
+ # col were not specified can still work (e.g., `add_vline`).
1191
+ if new_obj .xref is None :
1192
+ new_obj .xref = "x"
1193
+ if new_obj .yref is None :
1194
+ new_obj .yref = "y"
1195
+
1188
1196
self .layout [prop_plural ] += (new_obj ,)
1189
1197
1190
1198
return self
@@ -3473,6 +3481,13 @@ def _index_is(iterable, val):
3473
3481
return index_list [0 ]
3474
3482
3475
3483
def _make_paper_spanning_shape (self , direction , shape ):
3484
+ """
3485
+ Convert a shape drawn on a plot or a subplot into one whose yref or
3486
+ xref is 'paper' so that the shape will seem to extend infinitely in that
3487
+ dimension. This is useful for drawing lines or boxes on a plot where one
3488
+ dimension of the shape will not move out of bounds when moving the
3489
+ plot's view.
3490
+ """
3476
3491
if direction == "vertical" :
3477
3492
# fix y points to top and bottom of subplot
3478
3493
axis = "y"
@@ -3499,6 +3514,135 @@ def _make_paper_spanning_shape(self, direction, shape):
3499
3514
shape [ref ] = "paper"
3500
3515
return shape
3501
3516
3517
+ def _process_multiple_paper_spanning_shapes (
3518
+ self , shape_args , row , col , direction , ** kwargs
3519
+ ):
3520
+ """
3521
+ Add a shape or multiple shapes and call _make_paper_spanning_shape on
3522
+ all the new shapes.
3523
+ """
3524
+ # shapes are always added at the end of the tuple of shapes, so we see
3525
+ # how long the tuple is before the call and after the call, and adjust
3526
+ # the new shapes that were added at the end
3527
+ n_shapes_before = len (self .layout ["shapes" ])
3528
+ self .add_shape (row = row , col = col , ** shape_args , ** kwargs )
3529
+ n_shapes_after = len (self .layout ["shapes" ])
3530
+ new_shapes = tuple (
3531
+ [
3532
+ self ._make_paper_spanning_shape (direction , self .layout ["shapes" ][n ])
3533
+ for n in range (n_shapes_before , n_shapes_after )
3534
+ ]
3535
+ )
3536
+ self .layout ["shapes" ] = self .layout ["shapes" ][:n_shapes_before ] + new_shapes
3537
+
3538
+ def add_vline (self , x , row = None , col = None , ** kwargs ):
3539
+ """
3540
+ Add a vertical line to a plot or subplot that extends infinitely in the
3541
+ y-dimension.
3542
+
3543
+ Parameters
3544
+ ----------
3545
+ x: float or int
3546
+ A number representing the x coordinate of the vertical line.
3547
+ row: None, int or 'all'
3548
+ Subplot row for shape. If 'all', addresses all rows in
3549
+ the specified column(s). If both row and col are None, addresses the
3550
+ first subplot if subplots exist, or the only plot.
3551
+ col: None, int or 'all'
3552
+ Subplot col for shape. If 'all', addresses all columns in
3553
+ the specified row(s). If both row and col are None, addresses the
3554
+ first subplot if subplots exist, or the only plot.
3555
+ **kwargs:
3556
+ Any named function parameters that can be passed to 'add_shape',
3557
+ except for x0, x1, y0, x1 or type.
3558
+ """
3559
+ self ._process_multiple_paper_spanning_shapes (
3560
+ dict (type = "line" , x0 = x , x1 = x , y0 = 0 , y1 = 1 ), row , col , "vertical" , ** kwargs
3561
+ )
3562
+
3563
+ def add_hline (self , y , row = None , col = None , ** kwargs ):
3564
+ """
3565
+ Add a horizontal line to a plot or subplot that extends infinitely in the
3566
+ x-dimension.
3567
+
3568
+ Parameters
3569
+ ----------
3570
+ y: float or int
3571
+ A number representing the y coordinate of the horizontal line.
3572
+ row: None, int or 'all'
3573
+ Subplot row for shape. If 'all', addresses all rows in
3574
+ the specified column(s). If both row and col are None, addresses the
3575
+ first subplot if subplots exist, or the only plot.
3576
+ col: None, int or 'all'
3577
+ Subplot col for shape. If 'all', addresses all columns in
3578
+ the specified row(s). If both row and col are None, addresses the
3579
+ first subplot if subplots exist, or the only plot.
3580
+ **kwargs:
3581
+ Any named function parameters that can be passed to 'add_shape',
3582
+ except for x0, x1, y0, x1 or type.
3583
+ """
3584
+ self ._process_multiple_paper_spanning_shapes (
3585
+ dict (type = "line" , x0 = 0 , x1 = 1 , y0 = y , y1 = y ,), row , col , "horizontal" , ** kwargs
3586
+ )
3587
+
3588
+ def add_vrect (self , x0 , x1 , row = None , col = None , ** kwargs ):
3589
+ """
3590
+ Add a rectangle to a plot or subplot that extends infinitely in the
3591
+ y-dimension.
3592
+
3593
+ Parameters
3594
+ ----------
3595
+ x0: float or int
3596
+ A number representing the x coordinate of one side of the rectangle.
3597
+ x1: float or int
3598
+ A number representing the x coordinate of the other side of the rectangle.
3599
+ row: None, int or 'all'
3600
+ Subplot row for shape. If 'all', addresses all rows in
3601
+ the specified column(s). If both row and col are None, addresses the
3602
+ first subplot if subplots exist, or the only plot.
3603
+ col: None, int or 'all'
3604
+ Subplot col for shape. If 'all', addresses all columns in
3605
+ the specified row(s). If both row and col are None, addresses the
3606
+ first subplot if subplots exist, or the only plot.
3607
+ **kwargs:
3608
+ Any named function parameters that can be passed to 'add_shape',
3609
+ except for x0, x1, y0, x1 or type.
3610
+ """
3611
+ self ._process_multiple_paper_spanning_shapes (
3612
+ dict (type = "rect" , x0 = x0 , x1 = x1 , y0 = 0 , y1 = 1 ), row , col , "vertical" , ** kwargs
3613
+ )
3614
+
3615
+ def add_hrect (self , y0 , y1 , row = None , col = None , ** kwargs ):
3616
+ """
3617
+ Add a rectangle to a plot or subplot that extends infinitely in the
3618
+ x-dimension.
3619
+
3620
+ Parameters
3621
+ ----------
3622
+ y0: float or int
3623
+ A number representing the y coordinate of one side of the rectangle.
3624
+ y1: float or int
3625
+ A number representing the y coordinate of the other side of the rectangle.
3626
+ row: None, int or 'all'
3627
+ Subplot row for shape. If 'all', addresses all rows in
3628
+ the specified column(s). If both row and col are None, addresses the
3629
+ first subplot if subplots exist, or the only plot.
3630
+ col: None, int or 'all'
3631
+ Subplot col for shape. If 'all', addresses all columns in
3632
+ the specified row(s). If both row and col are None, addresses the
3633
+ first subplot if subplots exist, or the only plot.
3634
+ **kwargs:
3635
+ Any named function parameters that can be passed to 'add_shape',
3636
+ except for x0, x1, y0, x1 or type.
3637
+ """
3638
+ self ._process_multiple_paper_spanning_shapes (
3639
+ dict (type = "rect" , x0 = 0 , x1 = 1 , y0 = y0 , y1 = y1 ),
3640
+ row ,
3641
+ col ,
3642
+ "horizontal" ,
3643
+ ** kwargs
3644
+ )
3645
+
3502
3646
3503
3647
class BasePlotlyType (object ):
3504
3648
"""
0 commit comments