@@ -630,6 +630,9 @@ def make_subplots(rows=1, cols=1,
630
630
Space between subplot rows.
631
631
Applies to all rows (use 'specs' subplot-dependents spacing)
632
632
633
+ subplot_titles (kwarg, list of strings, default=empty list):
634
+ Title of each subplot.
635
+
633
636
specs (kwarg, list of lists of dictionaries):
634
637
Subplot specifications.
635
638
@@ -719,7 +722,7 @@ def make_subplots(rows=1, cols=1,
719
722
720
723
# Throw exception if non-valid kwarg is sent
721
724
VALID_KWARGS = ['horizontal_spacing' , 'vertical_spacing' ,
722
- 'specs' , 'insets' ]
725
+ 'specs' , 'insets' , 'subplot_titles' ]
723
726
for key in kwargs .keys ():
724
727
if key not in VALID_KWARGS :
725
728
raise Exception ("Invalid keyword argument: '{0}'" .format (key ))
@@ -734,6 +737,12 @@ def make_subplots(rows=1, cols=1,
734
737
except KeyError :
735
738
vertical_spacing = 0.3 / rows
736
739
740
+ # Set 'subplot_titles'
741
+ try :
742
+ subplot_titles = kwargs ['subplot_titles' ]
743
+ except KeyError :
744
+ subplot_titles = ["" ]* rows * cols
745
+
737
746
# Sanitize 'specs' (must be a list of lists)
738
747
exception_msg = "Keyword argument 'specs' must be a list of lists"
739
748
try :
@@ -906,6 +915,8 @@ def _get_anchors(r, c, x_cnt, y_cnt, shared_xaxes, shared_yaxes):
906
915
907
916
return x_anchor , y_anchor
908
917
918
+ list_of_domains = [] # added for subplot titles
919
+
909
920
# Function pasting x/y domains in layout object (2d case)
910
921
def _add_domain (layout , x_or_y , label , ___domain , anchor , position ):
911
922
name = label [0 ] + 'axis' + label [1 :]
@@ -916,11 +927,13 @@ def _add_domain(layout, x_or_y, label, ___domain, anchor, position):
916
927
if isinstance (position , float ):
917
928
axis ['position' ] = position
918
929
layout [name ] = axis
930
+ list_of_domains .append (___domain ) # added for subplot titles
919
931
920
932
# Function pasting x/y domains in layout object (3d case)
921
933
def _add_domain_is_3d (layout , s_label , x_domain , y_domain ):
922
934
scene = graph_objs .Scene (___domain = {'x' : x_domain , 'y' : y_domain })
923
935
layout [s_label ] = scene
936
+ list_of_domains .append (___domain ) # added for subplot titles
924
937
925
938
x_cnt = y_cnt = s_cnt = 1 # subplot axis/scene counters
926
939
@@ -1129,6 +1142,34 @@ def _pad(s, cell_len=cell_len):
1129
1142
s_str + _get_cell_str (r , c , ref ) + e_str + '\n '
1130
1143
)
1131
1144
1145
+ # Add subplot titles
1146
+ x_dom = list_of_domains [::2 ]
1147
+ y_dom = list_of_domains [1 ::2 ]
1148
+
1149
+ subtitle_pos_x = []
1150
+ for index in range (len (x_dom )):
1151
+ subtitle_pos_x .append (((x_dom [index ][1 ])- (x_dom [index ][0 ]))/ 2 +
1152
+ x_dom [index ][0 ])
1153
+
1154
+ subtitle_pos_y = []
1155
+ for index in range (len (y_dom )):
1156
+ subtitle_pos_y .append (y_dom [index ][1 ])
1157
+
1158
+ plot_titles = []
1159
+ for index in range (len (x_dom )):
1160
+ plot_titles .append ({'y' : subtitle_pos_y [index ],
1161
+ 'xref' : 'paper' ,
1162
+ 'x' : subtitle_pos_x [index ],
1163
+ 'yref' : 'paper' ,
1164
+ 'text' : subplot_titles [index ],
1165
+ 'showarrow' : False ,
1166
+ 'font' : Font (size = 18 ),
1167
+ 'xanchor' : 'center' ,
1168
+ 'yanchor' : 'bottom'
1169
+ })
1170
+
1171
+ layout ['annotations' ] = plot_titles
1172
+
1132
1173
if print_grid :
1133
1174
print (grid_str )
1134
1175
0 commit comments