@@ -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 :
@@ -3925,72 +3925,47 @@ def bxp(self, bxpstats, positions=None, widths=None, vert=True,
39253925
39263926 zdelta = 0.1
39273927
3928- def line_props_with_rcdefaults (subkey , explicit , zdelta = 0 ,
3929- use_marker = True ):
3928+ def merge_kw_rc (subkey , explicit , zdelta = 0 , usemarker = True ):
39303929 d = {k .split ('.' )[- 1 ]: v for k , v in rcParams .items ()
3931- if k .startswith (f'boxplot.{ subkey } ' )}
3930+ if k .startswith (f'boxplot.{ subkey } props ' )}
39323931 d ['zorder' ] = zorder + zdelta
3933- if not use_marker :
3932+ if not usemarker :
39343933 d ['marker' ] = ''
39353934 d .update (cbook .normalize_kwargs (explicit , mlines .Line2D ))
39363935 return d
39373936
3938- # box properties
3939- if patch_artist :
3940- final_boxprops = {
3941- 'linestyle' : rcParams ['boxplot.boxprops.linestyle' ],
3942- 'linewidth' : rcParams ['boxplot.boxprops.linewidth' ],
3943- 'edgecolor' : rcParams ['boxplot.boxprops.color' ],
3944- 'facecolor' : ('white' if rcParams ['_internal.classic_mode' ]
3945- else rcParams ['patch.facecolor' ]),
3946- 'zorder' : zorder ,
3947- ** cbook .normalize_kwargs (boxprops , mpatches .PathPatch )
3948- }
3949- else :
3950- final_boxprops = line_props_with_rcdefaults ('boxprops' , boxprops ,
3951- use_marker = False )
3952- final_whiskerprops = line_props_with_rcdefaults (
3953- 'whiskerprops' , whiskerprops , use_marker = False )
3954- final_capprops = line_props_with_rcdefaults (
3955- 'capprops' , capprops , use_marker = False )
3956- final_flierprops = line_props_with_rcdefaults (
3957- 'flierprops' , flierprops )
3958- final_medianprops = line_props_with_rcdefaults (
3959- 'medianprops' , medianprops , zdelta , use_marker = False )
3960- final_meanprops = line_props_with_rcdefaults (
3961- 'meanprops' , meanprops , zdelta )
3937+ box_kw = {
3938+ 'linestyle' : rcParams ['boxplot.boxprops.linestyle' ],
3939+ 'linewidth' : rcParams ['boxplot.boxprops.linewidth' ],
3940+ 'edgecolor' : rcParams ['boxplot.boxprops.color' ],
3941+ 'facecolor' : ('white' if rcParams ['_internal.classic_mode' ]
3942+ else rcParams ['patch.facecolor' ]),
3943+ 'zorder' : zorder ,
3944+ ** cbook .normalize_kwargs (boxprops , mpatches .PathPatch )
3945+ } if patch_artist else merge_kw_rc ('box' , boxprops , usemarker = False )
3946+ whisker_kw = merge_kw_rc ('whisker' , whiskerprops , usemarker = False )
3947+ cap_kw = merge_kw_rc ('cap' , capprops , usemarker = False )
3948+ flier_kw = merge_kw_rc ('flier' , flierprops )
3949+ median_kw = merge_kw_rc ('median' , medianprops , zdelta , usemarker = False )
3950+ mean_kw = merge_kw_rc ('mean' , meanprops , zdelta )
39623951 removed_prop = 'marker' if meanline else 'linestyle'
39633952 # Only remove the property if it's not set explicitly as a parameter.
39643953 if meanprops is None or removed_prop not in meanprops :
3965- final_meanprops [removed_prop ] = ''
3966-
3967- def patch_list (xs , ys , ** kwargs ):
3968- path = mpath .Path (
3969- # Last vertex will have a CLOSEPOLY code and thus be ignored.
3970- np .append (np .column_stack ([xs , ys ]), [(0 , 0 )], 0 ),
3971- closed = True )
3972- patch = mpatches .PathPatch (path , ** kwargs )
3973- self .add_artist (patch )
3974- return [patch ]
3954+ mean_kw [removed_prop ] = ''
39753955
39763956 # vertical or horizontal plot?
3977- if vert :
3978- def doplot (* args , ** kwargs ):
3979- return self .plot (* args , ** kwargs )
3980-
3981- def dopatch (xs , ys , ** kwargs ):
3982- return patch_list (xs , ys , ** kwargs )
3957+ maybe_swap = slice (None ) if vert else slice (None , None , - 1 )
39833958
3984- else :
3985- def doplot (* args , ** kwargs ):
3986- shuffled = []
3987- for i in range (0 , len (args ), 2 ):
3988- shuffled .extend ([args [i + 1 ], args [i ]])
3989- return self .plot (* shuffled , ** kwargs )
3959+ def do_plot (xs , ys , ** kwargs ):
3960+ return self .plot (* [xs , ys ][maybe_swap ], ** kwargs )[0 ]
39903961
3991- def dopatch (xs , ys , ** kwargs ):
3992- xs , ys = ys , xs # flip X, Y
3993- return patch_list (xs , ys , ** kwargs )
3962+ def do_patch (xs , ys , ** kwargs ):
3963+ path = mpath .Path (
3964+ # Last (0, 0) vertex has a CLOSEPOLY code and is thus ignored.
3965+ np .column_stack ([[* xs , 0 ], [* ys , 0 ]][maybe_swap ]), closed = True )
3966+ patch = mpatches .PathPatch (path , ** kwargs )
3967+ self .add_artist (patch )
3968+ return patch
39943969
39953970 # input validation
39963971 N = len (bxpstats )
@@ -4019,22 +3994,19 @@ def dopatch(xs, ys, **kwargs):
40193994 datalabels .append (stats .get ('label' , pos ))
40203995
40213996 # whisker coords
4022- whisker_x = np .ones (2 ) * pos
4023- whiskerlo_y = np .array ([stats ['q1' ], stats ['whislo' ]])
4024- whiskerhi_y = np .array ([stats ['q3' ], stats ['whishi' ]])
4025-
3997+ whis_x = [pos , pos ]
3998+ whislo_y = [stats ['q1' ], stats ['whislo' ]]
3999+ whishi_y = [stats ['q3' ], stats ['whishi' ]]
40264000 # cap coords
40274001 cap_left = pos - width * 0.25
40284002 cap_right = pos + width * 0.25
4029- cap_x = np .array ([cap_left , cap_right ])
4030- cap_lo = np .ones (2 ) * stats ['whislo' ]
4031- cap_hi = np .ones (2 ) * stats ['whishi' ]
4032-
4003+ cap_x = [cap_left , cap_right ]
4004+ cap_lo = np .full (2 , stats ['whislo' ])
4005+ cap_hi = np .full (2 , stats ['whishi' ])
40334006 # box and median coords
40344007 box_left = pos - width * 0.5
40354008 box_right = pos + width * 0.5
40364009 med_y = [stats ['med' ], stats ['med' ]]
4037-
40384010 # notched boxes
40394011 if shownotches :
40404012 box_x = [box_left , box_right , box_right , cap_right , box_right ,
@@ -4045,58 +4017,40 @@ def dopatch(xs, ys, **kwargs):
40454017 stats ['q3' ], stats ['cihi' ], stats ['med' ],
40464018 stats ['cilo' ], stats ['q1' ]]
40474019 med_x = cap_x
4048-
40494020 # plain boxes
40504021 else :
40514022 box_x = [box_left , box_right , box_right , box_left , box_left ]
40524023 box_y = [stats ['q1' ], stats ['q1' ], stats ['q3' ], stats ['q3' ],
40534024 stats ['q1' ]]
40544025 med_x = [box_left , box_right ]
40554026
4056- # maybe draw the box:
4027+ # maybe draw the box
40574028 if showbox :
4058- if patch_artist :
4059- boxes .extend (dopatch (box_x , box_y , ** final_boxprops ))
4060- else :
4061- boxes .extend (doplot (box_x , box_y , ** final_boxprops ))
4062-
4029+ do_box = do_patch if patch_artist else do_plot
4030+ boxes .append (do_box (box_x , box_y , ** box_kw ))
40634031 # draw the whiskers
4064- whiskers .extend (doplot (
4065- whisker_x , whiskerlo_y , ** final_whiskerprops
4066- ))
4067- whiskers .extend (doplot (
4068- whisker_x , whiskerhi_y , ** final_whiskerprops
4069- ))
4070-
4071- # maybe draw the caps:
4032+ whiskers .append (do_plot (whis_x , whislo_y , ** whisker_kw ))
4033+ whiskers .append (do_plot (whis_x , whishi_y , ** whisker_kw ))
4034+ # maybe draw the caps
40724035 if showcaps :
4073- caps .extend (doplot (cap_x , cap_lo , ** final_capprops ))
4074- caps .extend (doplot (cap_x , cap_hi , ** final_capprops ))
4075-
4036+ caps .append (do_plot (cap_x , cap_lo , ** cap_kw ))
4037+ caps .append (do_plot (cap_x , cap_hi , ** cap_kw ))
40764038 # draw the medians
4077- medians .extend (doplot (med_x , med_y , ** final_medianprops ))
4078-
4039+ medians .append (do_plot (med_x , med_y , ** median_kw ))
40794040 # maybe draw the means
40804041 if showmeans :
40814042 if meanline :
4082- means .extend ( doplot (
4043+ means .append ( do_plot (
40834044 [box_left , box_right ], [stats ['mean' ], stats ['mean' ]],
4084- ** final_meanprops
4045+ ** mean_kw
40854046 ))
40864047 else :
4087- means .extend (doplot (
4088- [pos ], [stats ['mean' ]], ** final_meanprops
4089- ))
4090-
4048+ means .append (do_plot ([pos ], [stats ['mean' ]], ** mean_kw ))
40914049 # maybe draw the fliers
40924050 if showfliers :
4093- # fliers coords
40944051 flier_x = np .full (len (stats ['fliers' ]), pos , dtype = np .float64 )
40954052 flier_y = stats ['fliers' ]
4096-
4097- fliers .extend (doplot (
4098- flier_x , flier_y , ** final_flierprops
4099- ))
4053+ fliers .append (do_plot (flier_x , flier_y , ** flier_kw ))
41004054
41014055 if manage_ticks :
41024056 axis_name = "x" if vert else "y"
0 commit comments