def _parse_validate_compile_intent(self): from lux.processor.Parser import Parser from lux.processor.Validator import Validator self._intent = Parser.parse(self._intent) Validator.validate_intent(self._intent, self) self.maintain_metadata() from lux.processor.Compiler import Compiler self.current_vis = Compiler.compile_intent(self, self._intent)
def recommendation(self): if self._recommendation is not None and self._recommendation == {}: from lux.processor.Compiler import Compiler self.maintain_metadata() self.current_vis = Compiler.compile_intent(self, self._intent) self.maintain_recs() return self._recommendation
def refresh_source(self, ldf): """ Loading the source into the visualizations in the VisList, then populating each visualization based on the new source data, effectively "materializing" the visualization collection. Parameters ---------- ldf : LuxDataframe Input Dataframe to be attached to the VisList Returns ------- VisList Complete VisList with fully-specified fields See Also -------- lux.vis.Vis.refresh_source Note ---- Function derives a new _inferred_intent by instantiating the intent specification on the new data """ if ldf is not None: from lux.processor.Parser import Parser from lux.processor.Validator import Validator from lux.processor.Compiler import Compiler self._source = ldf self._source.maintain_metadata() if len(self._input_lst) > 0: approx = False if self._is_vis_input(): compiled_collection = [] for vis in self._collection: vis._inferred_intent = Parser.parse(vis._intent) Validator.validate_intent(vis._inferred_intent, ldf) Compiler.compile_vis(ldf, vis) compiled_collection.append(vis) self._collection = compiled_collection else: self._inferred_intent = Parser.parse(self._intent) Validator.validate_intent(self._inferred_intent, ldf) self._collection = Compiler.compile_intent( ldf, self._inferred_intent) # Early pruning determination criteria width_criteria = len(self._collection) > (lux.config.topk + 3) length_criteria = len( ldf) > lux.config.early_pruning_sample_start if lux.config.early_pruning and width_criteria and length_criteria: # print("Apply approx to this VisList") ldf._message.add_unique( "Large search space detected: Lux is approximating the interestingness of recommended visualizations.", priority=1, ) approx = True lux.config.executor.execute(self._collection, ldf, approx=approx)
def refresh_source(self, ldf): """ Loading the source into the visualizations in the VisList, then populating each visualization based on the new source data, effectively "materializing" the visualization collection. Parameters ---------- ldf : LuxDataframe Input Dataframe to be attached to the VisList Returns ------- VisList Complete VisList with fully-specified fields See Also -------- lux.vis.Vis.refresh_source Note ---- Function derives a new _inferred_intent by instantiating the intent specification on the new data """ if (ldf is not None): from lux.processor.Parser import Parser from lux.processor.Validator import Validator from lux.processor.Compiler import Compiler self._source = ldf self._source.maintain_metadata() if len(self._input_lst) > 0: if (self._is_vis_input()): compiled_collection = [] for vis in self._collection: vis._inferred_intent = Parser.parse(vis._intent) Validator.validate_intent(vis._inferred_intent, ldf) vislist = Compiler.compile_vis(ldf, vis) if (len(vislist) > 0): vis = vislist[0] compiled_collection.append(vis) self._collection = compiled_collection else: self._inferred_intent = Parser.parse(self._intent) Validator.validate_intent(self._inferred_intent, ldf) self._collection = Compiler.compile_intent( ldf, self._inferred_intent) ldf.executor.execute(self._collection, ldf)
def set_intent_on_click(self, change): from IPython.display import display, clear_output from lux.processor.Compiler import Compiler intent_action = list(self._widget.selectedIntentIndex.keys())[0] vis = self.recommendation[intent_action][self._widget.selectedIntentIndex[intent_action][0]] self.set_intent_as_vis(vis) self.maintain_metadata() self.current_vis = Compiler.compile_intent(self, self._intent) self.maintain_recs() with self.output: clear_output() display(self._widget) self._widget.observe(self.remove_deleted_recs, names="deletedIndices") self._widget.observe(self.set_intent_on_click, names="selectedIntentIndex")
def _repr_html_(self): from IPython.display import display from IPython.display import clear_output import ipywidgets as widgets try: if self._pandas_only: display(self.display_pandas()) self._pandas_only = False else: if self.index.nlevels >= 2 or self.columns.nlevels >= 2: warnings.warn( "\nLux does not currently support dataframes " "with hierarchical indexes.\n" "Please convert the dataframe into a flat " "table via `pandas.DataFrame.reset_index`.\n", stacklevel=2, ) display(self.display_pandas()) return if len(self) <= 0: warnings.warn( "\nLux can not operate on an empty dataframe.\nPlease check your input again.\n", stacklevel=2, ) display(self.display_pandas()) return self.maintain_metadata() if self._intent != [] and (not hasattr(self, "_compiled") or not self._compiled): from lux.processor.Compiler import Compiler self.current_vis = Compiler.compile_intent(self, self._intent) if lux.config.default_display == "lux": self._toggle_pandas_display = False else: self._toggle_pandas_display = True # df_to_display.maintain_recs() # compute the recommendations (TODO: This can be rendered in another thread in the background to populate self._widget) self.maintain_recs() # Observers(callback_function, listen_to_this_variable) self._widget.observe(self.remove_deleted_recs, names="deletedIndices") self._widget.observe(self.set_intent_on_click, names="selectedIntentIndex") if len(self.recommendation) > 0: # box = widgets.Box(layout=widgets.Layout(display='inline')) button = widgets.Button( description="Toggle Pandas/Lux", layout=widgets.Layout(width="140px", top="5px"), ) self.output = widgets.Output() # box.children = [button,output] # output.children = [button] # display(box) display(button, self.output) def on_button_clicked(b): with self.output: if b: self._toggle_pandas_display = not self._toggle_pandas_display clear_output() if self._toggle_pandas_display: display(self.display_pandas()) else: # b.layout.display = "none" display(self._widget) # b.layout.display = "inline-block" button.on_click(on_button_clicked) on_button_clicked(None) else: warnings.warn( "\nLux defaults to Pandas when there are no valid actions defined.", stacklevel=2, ) display(self.display_pandas()) except (KeyboardInterrupt, SystemExit): raise except Exception: warnings.warn( "\nUnexpected error in rendering Lux widget and recommendations. " "Falling back to Pandas display.\n" "Please report the following issue on Github: https://github.com/lux-org/lux/issues \n", stacklevel=2, ) warnings.warn(traceback.format_exc()) display(self.display_pandas())
def _ipython_display_(self): from IPython.display import HTML, Markdown, display from IPython.display import clear_output import ipywidgets as widgets try: if self._pandas_only: display(self.display_pandas()) self._pandas_only = False if not self.index.nlevels >= 2 or self.columns.nlevels >= 2: self.maintain_metadata() if self._intent != [] and (not hasattr(self, "_compiled") or not self._compiled): from lux.processor.Compiler import Compiler self.current_vis = Compiler.compile_intent( self, self._intent) if lux.config.default_display == "lux": self._toggle_pandas_display = False else: self._toggle_pandas_display = True # df_to_display.maintain_recs() # compute the recommendations (TODO: This can be rendered in another thread in the background to populate self._widget) self.maintain_recs() # Observers(callback_function, listen_to_this_variable) self._widget.observe(self.remove_deleted_recs, names="deletedIndices") self._widget.observe(self.set_intent_on_click, names="selectedIntentIndex") button = widgets.Button( description="Toggle Table/Lux", layout=widgets.Layout(width="200px", top="6px", bottom="6px"), ) self.output = widgets.Output() self._sampled = lux.config.executor.execute_preview(self) display(button, self.output) def on_button_clicked(b): with self.output: if b: self._toggle_pandas_display = not self._toggle_pandas_display clear_output() # create connection string to display connect_str = self.table_name connection_type = str(type(lux.config.SQLconnection)) if "psycopg2.extensions.connection" in connection_type: connection_dsn = lux.config.SQLconnection.get_dsn_parameters( ) host_name = connection_dsn["host"] host_port = connection_dsn["port"] dbname = connection_dsn["dbname"] connect_str = host_name + ":" + host_port + "/" + dbname elif "sqlalchemy.engine.base.Engine" in connection_type: db_connection = str(lux.config.SQLconnection) db_start = db_connection.index("@") + 1 db_end = len(db_connection) - 1 connect_str = db_connection[db_start:db_end] if self._toggle_pandas_display: notification = "Here is a preview of the **{}** database table: **{}**".format( self.table_name, connect_str) display(Markdown(notification), self._sampled.display_pandas()) else: # b.layout.display = "none" display(self._widget) # b.layout.display = "inline-block" button.on_click(on_button_clicked) on_button_clicked(None) except (KeyboardInterrupt, SystemExit): raise except Exception: if lux.config.pandas_fallback: warnings.warn( "\nUnexpected error in rendering Lux widget and recommendations. " "Falling back to Pandas display.\n" "Please report the following issue on Github: https://github.com/lux-org/lux/issues \n", stacklevel=2, ) warnings.warn(traceback.format_exc()) display(self.display_pandas()) else: raise
def _repr_html_(self): from IPython.display import display from IPython.display import clear_output import ipywidgets as widgets try: if (self._pandas_only): display(self.display_pandas()) self._pandas_only = False else: if (self.index.nlevels >= 2 or self.columns.nlevels >= 2): warnings.warn( "\nLux does not currently support dataframes " "with hierarchical indexes.\n" "Please convert the dataframe into a flat " "table via `pandas.DataFrame.reset_index`.\n", stacklevel=2, ) display(self.display_pandas()) return if (len(self) <= 0): warnings.warn( "\nLux can not operate on an empty dataframe.\nPlease check your input again.\n", stacklevel=2) display(self.display_pandas()) return if (len(self.columns) <= 1): warnings.warn( "\nLux defaults to Pandas when there is only a single column.", stacklevel=2) display(self.display_pandas()) return self.maintain_metadata() if (self._intent != [] and (not hasattr(self, "_compiled") or not self._compiled)): from lux.processor.Compiler import Compiler self.current_vis = Compiler.compile_intent( self, self._intent) self._toggle_pandas_display = self._default_pandas_display # Reset to Pandas Vis everytime # df_to_display.maintain_recs() # compute the recommendations (TODO: This can be rendered in another thread in the background to populate self._widget) self.maintain_recs() # box = widgets.Box(layout=widgets.Layout(display='inline')) button = widgets.Button(description="Toggle Pandas/Lux", layout=widgets.Layout(width='140px', top='5px')) output = widgets.Output() # box.children = [button,output] # output.children = [button] # display(box) display(button, output) def on_button_clicked(b): with output: if (b): self._toggle_pandas_display = not self._toggle_pandas_display clear_output() if (self._toggle_pandas_display): display(self.display_pandas()) else: # b.layout.display = "none" display(self._widget) # b.layout.display = "inline-block" button.on_click(on_button_clicked) on_button_clicked(None) except (KeyboardInterrupt, SystemExit): raise except: warnings.warn( "\nUnexpected error in rendering Lux widget and recommendations. " "Falling back to Pandas display.\n\n" "Please report this issue on Github: https://github.com/lux-org/lux/issues ", stacklevel=2) display(self.display_pandas())
def _ipython_display_(self): from IPython.display import display from IPython.display import clear_output import ipywidgets as widgets try: if self._pandas_only: display(self.display_pandas()) self._pandas_only = False else: if not self.index.nlevels >= 2 or self.columns.nlevels >= 2: self.maintain_metadata() if self._intent != [] and (not hasattr(self, "_compiled") or not self._compiled): from lux.processor.Compiler import Compiler self.current_vis = Compiler.compile_intent( self, self._intent) if lux.config.default_display == "lux": self._toggle_pandas_display = False else: self._toggle_pandas_display = True # df_to_display.maintain_recs() # compute the recommendations (TODO: This can be rendered in another thread in the background to populate self._widget) self.maintain_recs() # Observers(callback_function, listen_to_this_variable) self._widget.observe(self.remove_deleted_recs, names="deletedIndices") self._widget.observe(self.set_intent_on_click, names="selectedIntentIndex") button = widgets.Button( description="Toggle Pandas/Lux", layout=widgets.Layout(width="140px", top="5px"), ) self.output = widgets.Output() display(button, self.output) def on_button_clicked(b): with self.output: if b: self._toggle_pandas_display = not self._toggle_pandas_display clear_output() if self._toggle_pandas_display: display(self.display_pandas()) else: # b.layout.display = "none" display(self._widget) # b.layout.display = "inline-block" button.on_click(on_button_clicked) on_button_clicked(None) except (KeyboardInterrupt, SystemExit): raise except Exception: if lux.config.pandas_fallback: warnings.warn( "\nUnexpected error in rendering Lux widget and recommendations. " "Falling back to Pandas display.\n" "Please report the following issue on Github: https://github.com/lux-org/lux/issues \n", stacklevel=2, ) warnings.warn(traceback.format_exc()) display(self.display_pandas()) else: raise