@@ -441,6 +441,8 @@ def __init__(self):
441441
442442 self .dist_color = QColor (* self .dist_color_RGB )
443443
444+ info_box = gui .vBox (self .controlArea , "Info" )
445+ self .info_text = gui .widgetLabel (info_box )
444446 self ._set_input_summary (None )
445447 self ._set_output_summary (None )
446448 gui .separator (self .controlArea )
@@ -712,6 +714,66 @@ def format_summary(summary):
712714 details = format_summary_details (slot .table )
713715 self .info .set_input_summary (summary , details )
714716
717+ self .info_text .setText ("\n " .join (self ._info_box_text (slot )))
718+
719+ def _info_box_text (self , slot ):
720+ def format_part (part ):
721+ if isinstance (part , DenseArray ):
722+ if not part .nans :
723+ return ""
724+ perc = 100 * part .nans / (part .nans + part .non_nans )
725+ return f" ({ perc :.1f} % missing data)"
726+
727+ if isinstance (part , SparseArray ):
728+ tag = "sparse"
729+ elif isinstance (part , SparseBoolArray ):
730+ tag = "tags"
731+ else : # isinstance(part, NotAvailable)
732+ return ""
733+ dens = 100 * part .non_nans / (part .nans + part .non_nans )
734+ return f" ({ tag } , density { dens :.2f} %)"
735+
736+ def desc (n , part ):
737+ if n == 0 :
738+ return f"No { part } s"
739+ elif n == 1 :
740+ return f"One { part } "
741+ else :
742+ return f"{ n } { part } s"
743+
744+ if slot is None :
745+ return "No data."
746+ summary = slot .summary
747+ text = []
748+ if isinstance (summary , ApproxSummary ):
749+ if summary .len .done ():
750+ text .append (f"{ summary .len .result ()} instances" )
751+ else :
752+ text .append (f"~{ summary .approx_len } instances" )
753+ elif isinstance (summary , Summary ):
754+ text .append (f"{ summary .len } instances" )
755+ if sum (p .nans for p in [summary .X , summary .Y , summary .M ]) == 0 :
756+ text [- 1 ] += " (no missing data)"
757+
758+ text .append (desc (len (summary .domain .attributes ), "feature" )
759+ + format_part (summary .X ))
760+
761+ if not summary .domain .class_vars :
762+ text .append ("No target variable." )
763+ else :
764+ if len (summary .domain .class_vars ) > 1 :
765+ c_text = desc (len (summary .domain .class_vars ), "outcome" )
766+ elif summary .domain .has_continuous_class :
767+ c_text = "Numeric outcome"
768+ else :
769+ c_text = "Target with " \
770+ + desc (len (summary .domain .class_var .values ), "value" )
771+ text .append (c_text + format_part (summary .Y ))
772+
773+ text .append (desc (len (summary .domain .metas ), "meta attribute" )
774+ + format_part (summary .M ))
775+ return text
776+
715777 def _set_output_summary (self , output ):
716778 summary = len (output ) if output else self .info .NoOutput
717779 details = format_summary_details (output ) if output else ""
0 commit comments