44
55import numpy
66import pandas
7- from sys import float_info
87
98from matplotlib .backends .backend_agg import FigureCanvasAgg
109from matplotlib .figure import Figure
1110import matplotlib .cm as mcm
1211import matplotlib .colors as mc
13- import matplotlib as mpl
1412import matplotlib .table as mt
1513import matplotlib .ticker as mtick
1614
17- from ..metrics .metricset import MetricSet
18- from ..utils .plot import approx_string_em_width , get_pop_logo_data
15+ from pypop .metrics .metricset import MetricSet
16+ from pypop .utils .plot import approx_string_em_width , get_pop_logo_data
17+
18+ from .mplplotbase import MPLPlotBase
19+
20+ __all__ = ["MPLMetricTable" , "MPLScalingPlot" ]
1921
2022
2123def build_discrete_cmap (factors ):
@@ -31,28 +33,6 @@ def build_discrete_cmap(factors):
3133 return {k : cmap (i / (len (factors ) - 1 )) for i , k in enumerate (factors )}
3234
3335
34- class MPLPlotBase (object ):
35- def __init__ (self ):
36- self ._figure = None
37-
38- def _build_plot (self ):
39- raise NotImplementedError ("MPLPlotBase should not be used directly!" )
40-
41- @property
42- def figure (self ):
43- if not self ._figure :
44- self ._build_plot ()
45- return self ._figure
46-
47- def _repr_png_ (self ):
48- imgbuffer = BytesIO ()
49- self .figure .savefig (imgbuffer , format = "png" )
50- return imgbuffer .getvalue ()
51-
52- def save_png (self , filename ):
53- self .figure .savefig (filename , format = "png" )
54-
55-
5636class MPLScalingPlot (MPLPlotBase ):
5737 def __init__ (
5838 self ,
@@ -174,8 +154,6 @@ def _build_plot(self):
174154 lw = 0 ,
175155 )
176156
177- xmin = float_info .max
178- xmax = 0
179157 for group , groupdata in plot_data .groupby ("Plotgroups" , sort = False ):
180158 groupdata = groupdata .sort_values (self ._xaxis_key )
181159 self ._figax .plot (
@@ -346,15 +324,12 @@ def _build_plot(self):
346324 self ._logo_height / plot_height , # Logo height
347325 ]
348326
349- print ("Logo Ax: {:.2f}, {:.2f}, {:.2f}, {:.2f}" .format (* logo_ax_layout ))
350-
351327 self ._logo_ax = self ._figure .add_axes (logo_ax_layout , frame_on = False )
352328 self ._logo_ax .xaxis .set_visible (False )
353329 self ._logo_ax .yaxis .set_visible (False )
354330
355331 self ._logo_ax .imshow (pop_data , origin = "lower" )
356332
357- print ("Tabl Ax: {:.2f}, {:.2f}, {:.2f}, {:.2f}" .format (* table_ax_layout ))
358333 self ._table_ax = self ._figure .add_axes (table_ax_layout , frame_on = False )
359334
360335 self ._table_ax .xaxis .set_visible (False )
@@ -501,120 +476,3 @@ def efficiency_cmap(self, value):
501476 return self ._eff_cmap (- 1 )
502477
503478 return self ._eff_cmap (value )
504-
505-
506- def _plot_table (
507- self , columns_key , title , columns_label , good_thres , bad_thres , skipfirst , bwfirst ,
508- ):
509-
510- if not columns_key :
511- columns_values = self .metric_data .index
512- if columns_label is None :
513- columns_label = "Index"
514- else :
515- columns_values = self .metric_data [columns_key ]
516- if not columns_label :
517- columns_label = columns_key
518-
519- label_cell_width = 0.60
520- body_cell_width = (1 - label_cell_width ) / (len (columns_values ) - skipfirst )
521- body_cell_height = 0.1
522- level_pad = 0.075
523-
524- pop_red = (0.690 , 0.074 , 0.074 )
525- pop_fade = (0.992 , 0.910 , 0.910 )
526- pop_green = (0.074 , 0.690 , 0.074 )
527-
528- ineff_points = [
529- (0.0 , pop_green ),
530- (1 - good_thres , pop_fade ),
531- (1 - good_thres + 1e-20 , pop_fade ),
532- (1 - bad_thres , pop_red ),
533- (1.0 , pop_red ),
534- ]
535-
536- eff_points = [
537- (0.0 , pop_red ),
538- (bad_thres , pop_red ),
539- (good_thres - 1e-20 , pop_fade ),
540- (good_thres , pop_fade ),
541- (1.0 , pop_green ),
542- ]
543-
544- ineff_cmap = mc .LinearSegmentedColormap .from_list (
545- "POP_Metrics" , colors = ineff_points , N = 256 , gamma = 1
546- )
547-
548- eff_cmap = mc .LinearSegmentedColormap .from_list (
549- "POP_Metrics" , colors = eff_points , N = 256 , gamma = 1
550- )
551-
552- label_cell_kwargs = {
553- "loc" : "left" ,
554- "width" : label_cell_width ,
555- "height" : body_cell_height ,
556- }
557- body_cell_kwargs = {
558- "loc" : "center" ,
559- "width" : body_cell_width ,
560- "height" : body_cell_height ,
561- }
562-
563- fig = plt .figure (figsize = figparams ["single.figsize" ])
564- ax = [fig .add_axes (fp ) for fp in figparams ["single.axlayout" ]]
565- ax [0 ].set_axis_off ()
566-
567- # Create empty table using full bounding box of axes
568- metric_table = mt .Table (ax = ax [0 ], bbox = (0 , 0 , 1 , 1 ))
569- metric_table .auto_set_font_size (True )
570- # metric_table.set_fontsize(8)
571-
572- metric_table .add_cell (
573- 0 ,
574- 0 ,
575- width = label_cell_width ,
576- height = body_cell_height ,
577- text = columns_label ,
578- loc = "center" ,
579- )
580-
581- for col_num , col_data in enumerate (columns_values , start = 1 ):
582- if col_num <= skipfirst :
583- continue
584- metric_table .add_cell (
585- 0 , col_num - skipfirst , text = "{}" .format (col_data ), ** body_cell_kwargs
586- )
587-
588- for row_num , metric in enumerate (self .metrics , start = 1 ):
589- cmap = ineff_cmap if metric .is_inefficiency else eff_cmap
590- c = metric_table .add_cell (
591- row_num , 0 , text = metric .displayname , ** label_cell_kwargs
592- )
593- c .PAD = 0.05
594- c .PAD += 0 if metric .level <= 1 else level_pad * (metric .level - 1 )
595-
596- for col_num , col_data in enumerate (self .metric_data [metric .key ], start = 1 ):
597- if col_num <= skipfirst :
598- continue
599- if col_num <= bwfirst :
600- metric_table .add_cell (
601- row_num ,
602- col_num ,
603- text = "{:1.02f}" .format (col_data ),
604- ** body_cell_kwargs
605- )
606- else :
607- metric_table .add_cell (
608- row_num ,
609- col_num - skipfirst ,
610- text = "{:1.02f}" .format (col_data ),
611- facecolor = cmap (col_data ),
612- ** body_cell_kwargs
613- )
614-
615- ax [0 ].add_table (metric_table )
616-
617- if title :
618- ax [0 ].set_title (title )
619-
620- return fig
0 commit comments