@@ -3746,7 +3746,7 @@ def boxplot(self, x, notch=None, sym=None, vert=None, whis=None,
37463746
37473747 # if non-default sym value, put it into the flier dictionary
37483748 # the logic for providing the default symbol ('b+') now lives
3749- # in bxp in the initial value of final_flierprops
3749+ # in bxp in the initial value of flierkw
37503750 # handle all of the *sym* related logic here so we only have to pass
37513751 # on the flierprops dict.
37523752 if sym is not None :
@@ -3974,72 +3974,47 @@ def bxp(self, bxpstats, positions=None, widths=None, vert=True,
39743974
39753975 zdelta = 0.1
39763976
3977- def line_props_with_rcdefaults (subkey , explicit , zdelta = 0 ,
3978- use_marker = True ):
3977+ def merge_kw_rc (subkey , explicit , zdelta = 0 , usemarker = True ):
39793978 d = {k .split ('.' )[- 1 ]: v for k , v in rcParams .items ()
3980- if k .startswith (f'boxplot.{ subkey } ' )}
3979+ if k .startswith (f'boxplot.{ subkey } props ' )}
39813980 d ['zorder' ] = zorder + zdelta
3982- if not use_marker :
3981+ if not usemarker :
39833982 d ['marker' ] = ''
39843983 d .update (cbook .normalize_kwargs (explicit , mlines .Line2D ))
39853984 return d
39863985
3987- # box properties
3988- if patch_artist :
3989- final_boxprops = {
3990- 'linestyle' : rcParams ['boxplot.boxprops.linestyle' ],
3991- 'linewidth' : rcParams ['boxplot.boxprops.linewidth' ],
3992- 'edgecolor' : rcParams ['boxplot.boxprops.color' ],
3993- 'facecolor' : ('white' if rcParams ['_internal.classic_mode' ]
3994- else rcParams ['patch.facecolor' ]),
3995- 'zorder' : zorder ,
3996- ** cbook .normalize_kwargs (boxprops , mpatches .PathPatch )
3997- }
3998- else :
3999- final_boxprops = line_props_with_rcdefaults ('boxprops' , boxprops ,
4000- use_marker = False )
4001- final_whiskerprops = line_props_with_rcdefaults (
4002- 'whiskerprops' , whiskerprops , use_marker = False )
4003- final_capprops = line_props_with_rcdefaults (
4004- 'capprops' , capprops , use_marker = False )
4005- final_flierprops = line_props_with_rcdefaults (
4006- 'flierprops' , flierprops )
4007- final_medianprops = line_props_with_rcdefaults (
4008- 'medianprops' , medianprops , zdelta , use_marker = False )
4009- final_meanprops = line_props_with_rcdefaults (
4010- 'meanprops' , meanprops , zdelta )
3986+ box_kw = {
3987+ 'linestyle' : rcParams ['boxplot.boxprops.linestyle' ],
3988+ 'linewidth' : rcParams ['boxplot.boxprops.linewidth' ],
3989+ 'edgecolor' : rcParams ['boxplot.boxprops.color' ],
3990+ 'facecolor' : ('white' if rcParams ['_internal.classic_mode' ]
3991+ else rcParams ['patch.facecolor' ]),
3992+ 'zorder' : zorder ,
3993+ ** cbook .normalize_kwargs (boxprops , mpatches .PathPatch )
3994+ } if patch_artist else merge_kw_rc ('box' , boxprops , usemarker = False )
3995+ whisker_kw = merge_kw_rc ('whisker' , whiskerprops , usemarker = False )
3996+ cap_kw = merge_kw_rc ('cap' , capprops , usemarker = False )
3997+ flier_kw = merge_kw_rc ('flier' , flierprops )
3998+ median_kw = merge_kw_rc ('median' , medianprops , zdelta , usemarker = False )
3999+ mean_kw = merge_kw_rc ('mean' , meanprops , zdelta )
40114000 removed_prop = 'marker' if meanline else 'linestyle'
40124001 # Only remove the property if it's not set explicitly as a parameter.
40134002 if meanprops is None or removed_prop not in meanprops :
4014- final_meanprops [removed_prop ] = ''
4015-
4016- def patch_list (xs , ys , ** kwargs ):
4017- path = mpath .Path (
4018- # Last vertex will have a CLOSEPOLY code and thus be ignored.
4019- np .append (np .column_stack ([xs , ys ]), [(0 , 0 )], 0 ),
4020- closed = True )
4021- patch = mpatches .PathPatch (path , ** kwargs )
4022- self .add_artist (patch )
4023- return [patch ]
4003+ mean_kw [removed_prop ] = ''
40244004
40254005 # vertical or horizontal plot?
4026- if vert :
4027- def doplot (* args , ** kwargs ):
4028- return self .plot (* args , ** kwargs )
4029-
4030- def dopatch (xs , ys , ** kwargs ):
4031- return patch_list (xs , ys , ** kwargs )
4006+ maybe_swap = slice (None ) if vert else slice (None , None , - 1 )
40324007
4033- else :
4034- def doplot (* args , ** kwargs ):
4035- shuffled = []
4036- for i in range (0 , len (args ), 2 ):
4037- shuffled .extend ([args [i + 1 ], args [i ]])
4038- return self .plot (* shuffled , ** kwargs )
4008+ def do_plot (xs , ys , ** kwargs ):
4009+ return self .plot (* [xs , ys ][maybe_swap ], ** kwargs )[0 ]
40394010
4040- def dopatch (xs , ys , ** kwargs ):
4041- xs , ys = ys , xs # flip X, Y
4042- return patch_list (xs , ys , ** kwargs )
4011+ def do_patch (xs , ys , ** kwargs ):
4012+ path = mpath .Path (
4013+ # Last (0, 0) vertex has a CLOSEPOLY code and is thus ignored.
4014+ np .column_stack ([[* xs , 0 ], [* ys , 0 ]][maybe_swap ]), closed = True )
4015+ patch = mpatches .PathPatch (path , ** kwargs )
4016+ self .add_artist (patch )
4017+ return patch
40434018
40444019 # input validation
40454020 N = len (bxpstats )
@@ -4068,22 +4043,19 @@ def dopatch(xs, ys, **kwargs):
40684043 datalabels .append (stats .get ('label' , pos ))
40694044
40704045 # whisker coords
4071- whisker_x = np .ones (2 ) * pos
4072- whiskerlo_y = np .array ([stats ['q1' ], stats ['whislo' ]])
4073- whiskerhi_y = np .array ([stats ['q3' ], stats ['whishi' ]])
4074-
4046+ whis_x = [pos , pos ]
4047+ whislo_y = [stats ['q1' ], stats ['whislo' ]]
4048+ whishi_y = [stats ['q3' ], stats ['whishi' ]]
40754049 # cap coords
40764050 cap_left = pos - width * 0.25
40774051 cap_right = pos + width * 0.25
4078- cap_x = np .array ([cap_left , cap_right ])
4079- cap_lo = np .ones (2 ) * stats ['whislo' ]
4080- cap_hi = np .ones (2 ) * stats ['whishi' ]
4081-
4052+ cap_x = [cap_left , cap_right ]
4053+ cap_lo = np .full (2 , stats ['whislo' ])
4054+ cap_hi = np .full (2 , stats ['whishi' ])
40824055 # box and median coords
40834056 box_left = pos - width * 0.5
40844057 box_right = pos + width * 0.5
40854058 med_y = [stats ['med' ], stats ['med' ]]
4086-
40874059 # notched boxes
40884060 if shownotches :
40894061 box_x = [box_left , box_right , box_right , cap_right , box_right ,
@@ -4094,58 +4066,40 @@ def dopatch(xs, ys, **kwargs):
40944066 stats ['q3' ], stats ['cihi' ], stats ['med' ],
40954067 stats ['cilo' ], stats ['q1' ]]
40964068 med_x = cap_x
4097-
40984069 # plain boxes
40994070 else :
41004071 box_x = [box_left , box_right , box_right , box_left , box_left ]
41014072 box_y = [stats ['q1' ], stats ['q1' ], stats ['q3' ], stats ['q3' ],
41024073 stats ['q1' ]]
41034074 med_x = [box_left , box_right ]
41044075
4105- # maybe draw the box:
4076+ # maybe draw the box
41064077 if showbox :
4107- if patch_artist :
4108- boxes .extend (dopatch (box_x , box_y , ** final_boxprops ))
4109- else :
4110- boxes .extend (doplot (box_x , box_y , ** final_boxprops ))
4111-
4078+ do_box = do_patch if patch_artist else do_plot
4079+ boxes .append (do_box (box_x , box_y , ** box_kw ))
41124080 # draw the whiskers
4113- whiskers .extend (doplot (
4114- whisker_x , whiskerlo_y , ** final_whiskerprops
4115- ))
4116- whiskers .extend (doplot (
4117- whisker_x , whiskerhi_y , ** final_whiskerprops
4118- ))
4119-
4120- # maybe draw the caps:
4081+ whiskers .append (do_plot (whis_x , whislo_y , ** whisker_kw ))
4082+ whiskers .append (do_plot (whis_x , whishi_y , ** whisker_kw ))
4083+ # maybe draw the caps
41214084 if showcaps :
4122- caps .extend (doplot (cap_x , cap_lo , ** final_capprops ))
4123- caps .extend (doplot (cap_x , cap_hi , ** final_capprops ))
4124-
4085+ caps .append (do_plot (cap_x , cap_lo , ** cap_kw ))
4086+ caps .append (do_plot (cap_x , cap_hi , ** cap_kw ))
41254087 # draw the medians
4126- medians .extend (doplot (med_x , med_y , ** final_medianprops ))
4127-
4088+ medians .append (do_plot (med_x , med_y , ** median_kw ))
41284089 # maybe draw the means
41294090 if showmeans :
41304091 if meanline :
4131- means .extend ( doplot (
4092+ means .append ( do_plot (
41324093 [box_left , box_right ], [stats ['mean' ], stats ['mean' ]],
4133- ** final_meanprops
4094+ ** mean_kw
41344095 ))
41354096 else :
4136- means .extend (doplot (
4137- [pos ], [stats ['mean' ]], ** final_meanprops
4138- ))
4139-
4097+ means .append (do_plot ([pos ], [stats ['mean' ]], ** mean_kw ))
41404098 # maybe draw the fliers
41414099 if showfliers :
4142- # fliers coords
41434100 flier_x = np .full (len (stats ['fliers' ]), pos , dtype = np .float64 )
41444101 flier_y = stats ['fliers' ]
4145-
4146- fliers .extend (doplot (
4147- flier_x , flier_y , ** final_flierprops
4148- ))
4102+ fliers .append (do_plot (flier_x , flier_y , ** flier_kw ))
41494103
41504104 if manage_ticks :
41514105 axis_name = "x" if vert else "y"
0 commit comments