@@ -1302,7 +1302,7 @@ def _add_annotation_like(
1302
1302
# if exclude_empty_subplots is True, check to see if subplot is
1303
1303
# empty and return if it is
1304
1304
if exclude_empty_subplots and (
1305
- not self ._subplot_contains_trace (xref , yref )
1305
+ not self ._subplot_not_empty (xref , yref , selector = exclude_empty_subplots )
1306
1306
):
1307
1307
return self
1308
1308
# in case the user specified they wanted an axis to refer to the
@@ -1993,8 +1993,8 @@ def add_traces(
1993
1993
if exclude_empty_subplots :
1994
1994
data = list (
1995
1995
filter (
1996
- lambda trace : self ._subplot_contains_trace (
1997
- trace ["xaxis" ], trace ["yaxis" ]
1996
+ lambda trace : self ._subplot_not_empty (
1997
+ trace ["xaxis" ], trace ["yaxis" ], exclude_empty_subplots
1998
1998
),
1999
1999
data ,
2000
2000
)
@@ -3873,19 +3873,56 @@ def _has_subplots(self):
3873
3873
single plot and so this returns False. """
3874
3874
return self ._grid_ref is not None
3875
3875
3876
- def _subplot_contains_trace (self , xref , yref ):
3877
- return any (
3878
- t == (xref , yref )
3879
- for t in [
3880
- # if a trace exists but has no xaxis or yaxis keys, then it
3881
- # is plotted with xaxis 'x' and yaxis 'y'
3882
- (
3883
- "x" if d ["xaxis" ] is None else d ["xaxis" ],
3884
- "y" if d ["yaxis" ] is None else d ["yaxis" ],
3876
+ def _subplot_not_empty (self , xref , yref , selector = "all" ):
3877
+ """
3878
+ xref: string representing the axis. Objects in the plot will be checked
3879
+ for this xref (for layout objects) or xaxis (for traces) to
3880
+ determine if they lie in a certain subplot.
3881
+ yref: string representing the axis. Objects in the plot will be checked
3882
+ for this yref (for layout objects) or yaxis (for traces) to
3883
+ determine if they lie in a certain subplot.
3884
+ selector: can be "all" or an iterable containing some combination of
3885
+ "traces", "shapes", "annotations", "images". Only the presence
3886
+ of objects specified in selector will be checked. So if
3887
+ ["traces","shapes"] is passed then a plot we be considered
3888
+ non-empty if it contains traces or shapes. If
3889
+ bool(selector) returns False, no checking is performed and
3890
+ this function returns True. If selector is True, it is
3891
+ converted to "all".
3892
+ """
3893
+ if not selector :
3894
+ # If nothing to select was specified then a subplot is always deemed non-empty
3895
+ return True
3896
+ if selector == True :
3897
+ selector = "all"
3898
+ if selector == "all" :
3899
+ selector = ["traces" , "shapes" , "annotations" , "images" ]
3900
+ ret = False
3901
+ for s in selector :
3902
+ if s == "traces" :
3903
+ obj = self .data
3904
+ xaxiskw = "xaxis"
3905
+ yaxiskw = "yaxis"
3906
+ elif s in ["shapes" , "annotations" , "images" ]:
3907
+ obj = self .layout [s ]
3908
+ xaxiskw = "xref"
3909
+ yaxiskw = "yref"
3910
+ else :
3911
+ obj = None
3912
+ if obj :
3913
+ ret |= any (
3914
+ t == (xref , yref )
3915
+ for t in [
3916
+ # if a object exists but has no xaxis or yaxis keys, then it
3917
+ # is plotted with xaxis/xref 'x' and yaxis/yref 'y'
3918
+ (
3919
+ "x" if d [xaxiskw ] is None else d [xaxiskw ],
3920
+ "y" if d [yaxiskw ] is None else d [yaxiskw ],
3921
+ )
3922
+ for d in obj
3923
+ ]
3885
3924
)
3886
- for d in self .data
3887
- ]
3888
- )
3925
+ return ret
3889
3926
3890
3927
3891
3928
class BasePlotlyType (object ):
0 commit comments