def __init__(self, pgdf: PandasGuiDataFrame): super().__init__() pgdf = PandasGuiDataFrame.cast(pgdf) pgdf.filter_viewer = self self.pgdf = pgdf self.list_view = self.ListView() self.list_model = self.ListModel(pgdf) self.list_view.setModel(self.list_model) self.text_input = QtWidgets.QLineEdit() self.text_input.setPlaceholderText("Enter query expression") self.text_input_label = QtWidgets.QLabel( '''<a href="https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.query.html">What's a query expression?</a>''' ) self.text_input_label.linkActivated.connect( lambda link: QDesktopServices.openUrl(QUrl(link))) self.text_input.setValidator(None) self.submit_button = QtWidgets.QPushButton("Add Filter") # Signals self.text_input.returnPressed.connect(self.add_filter) self.submit_button.clicked.connect(self.add_filter) # Layout self.new_filter_layout = QtWidgets.QHBoxLayout() self.new_filter_layout.addWidget(self.text_input) self.new_filter_layout.addWidget(self.submit_button) self.layout = QtWidgets.QVBoxLayout() self.layout.addLayout(self.new_filter_layout) self.layout.addWidget(self.text_input_label) self.layout.addWidget(self.list_view) self.setLayout(self.layout)
def __init__(self, pgdf: PandasGuiDataFrame): super().__init__() self.pgdf = PandasGuiDataFrame.cast(pgdf) self.setWindowTitle("Graph Builder") self.workers = [] self.current_worker = None # Dropdown to select plot type self.plot_type_picker = QtWidgets.QListWidget() self.plot_type_picker.setViewMode(self.plot_type_picker.IconMode) self.plot_type_picker.setWordWrap(True) self.plot_type_picker.setSpacing(20) self.plot_type_picker.setResizeMode(self.plot_type_picker.Adjust) self.plot_type_picker.setDragDropMode(self.plot_type_picker.NoDragDrop) self.plot_type_picker.sizeHint = lambda: QtCore.QSize(500, 250) for schema in schemas: icon = QtGui.QIcon(schema.icon_path) text = schema.label item = QtWidgets.QListWidgetItem(icon, text) self.plot_type_picker.addItem(item) # UI setup self.figure_viewer = PlotlyViewer() self.figure_viewer.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding) df = flatten_df(self.pgdf.dataframe) self.dragger = Dragger(sources=df.columns, destinations=[], source_types=df.dtypes.values.astype(str)) self.spinner = Spinner() self.spinner.setParent(self.figure_viewer) self.layout = QtWidgets.QGridLayout() self.layout.addWidget(self.plot_type_picker, 0, 0) self.layout.addWidget(self.dragger, 1, 0) self.layout.addWidget(self.figure_viewer, 0, 1, 2, 1) self.layout.setColumnStretch(0, 0) self.layout.setColumnStretch(1, 1) self.dragger.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding) self.plot_type_picker.setSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred) self.setLayout(self.layout) # Signals self.plot_type_picker.itemSelectionChanged.connect(self.on_type_changed) self.dragger.finished.connect(self.on_dragger_finished) # Initial selection self.plot_type_picker.setSelectionMode(QtWidgets.QAbstractItemView.SingleSelection) self.plot_type_picker.setCurrentRow(0) self.on_type_changed() # Show a blank axis initially self.figure_viewer.set_figure(plotly.graph_objs.Figure())
def __init__(self, pgdf: PandasGuiDataFrame): super().__init__() pgdf = PandasGuiDataFrame.cast(pgdf) pgdf.dataframe_explorer = self self.pgdf = pgdf # Dock setup self.docks: List[DockWidget] = [] self.setDockOptions(self.GroupedDragging | self.AllowTabbedDocks | self.AllowNestedDocks) self.setTabPosition(Qt.AllDockWidgetAreas, QtWidgets.QTabWidget.North) # DataFrame tab self.dataframe_tab = DataFrameViewer(pgdf) self.dataframe_dock = self.add_view(self.dataframe_tab, "DataFrame") # Filters tab self.filters_tab = FilterViewer(pgdf) self.filters_dock = self.add_view(self.filters_tab, "Filters") # Statistics tab self.statistics_tab = self.make_statistics_tab(pgdf) self.statistics_dock = self.add_view(self.statistics_tab, "Statistics") # Grapher tab self.grapher_tab = Grapher(pgdf) self.grapher_dock = self.add_view(self.grapher_tab, "Grapher") # Layout self.dataframe_tab.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
def add_df(self, df: pd.DataFrame, name: str): """ Add a new DataFrame to the GUI """ pgdf = PandasGuiDataFrame.cast(df) pgdf.name = name self.store.add_pgdf(pgdf) dfe = DataFrameExplorer(pgdf) self.stacked_widget.addWidget(dfe) self.add_df_to_nav(name)
def __init__(self, pgdf: PandasGuiDataFrame): super().__init__() self.pgdf = PandasGuiDataFrame.cast(pgdf) self.prev_kwargs = ({}) # This is for carrying plot arg selections forward to new plot types self.setWindowTitle("Graph Builder") self.workers = [] self.current_worker = None # Dropdown to select plot type self.plot_type_picker = QtWidgets.QListWidget() for schema in schemas: icon = QtGui.QIcon(schema.icon_path) text = schema.label item = QtWidgets.QListWidgetItem(icon, text) self.plot_type_picker.addItem(item) # UI setup self.figure_viewer = PlotlyViewer() self.figure_viewer.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding) df = self.get_df() self.dragger = Dragger(sources=df.columns, destinations=[], source_types=df.dtypes.values.astype(str)) self.spinner = Spinner() self.spinner.setParent(self.figure_viewer) self.layout = QtWidgets.QGridLayout() self.layout.addWidget(self.plot_type_picker, 0, 0) self.layout.addWidget(self.dragger, 1, 0) self.layout.addWidget(self.figure_viewer, 0, 1, 2, 1) self.layout.setColumnStretch(0, 0) self.layout.setColumnStretch(1, 1) self.setLayout(self.layout) # Signals self.plot_type_picker.itemSelectionChanged.connect(self.update_dragger) self.dragger.finished.connect(self.update_plot) # Initial selection self.plot_type_picker.setSelectionMode(QtWidgets.QAbstractItemView.SingleSelection) self.plot_type_picker.setCurrentRow(0) self.update_dragger() # Show a blank axis initially self.figure_viewer.set_figure(px.scatter())
def __init__(self, pgdf: PandasGuiDataFrame): super().__init__() self.pgdf = PandasGuiDataFrame.cast(pgdf) self.setWindowTitle("Reshaper") # Dropdown to select reshape type self.reshape_type_picker = QtWidgets.QListWidget() self.reshape_type_picker.setViewMode(self.reshape_type_picker.IconMode) self.reshape_type_picker.setWordWrap(True) self.reshape_type_picker.setSpacing(20) self.reshape_type_picker.setResizeMode(self.reshape_type_picker.Adjust) self.reshape_type_picker.setDragDropMode(self.reshape_type_picker.NoDragDrop) for schema in schemas: icon = QtGui.QIcon(schema.icon_path) text = schema.label item = QtWidgets.QListWidgetItem(icon, text) self.reshape_type_picker.addItem(item) df = flatten_df(self.pgdf.dataframe) self.dragger = Dragger(sources=df.columns, destinations=[], source_types=df.dtypes.values.astype(str)) self.layout = QtWidgets.QGridLayout() self.layout.addWidget(self.reshape_type_picker, 0, 0) self.layout.addWidget(self.dragger, 1, 0) self.layout.setColumnStretch(0, 0) self.layout.setColumnStretch(1, 1) self.dragger.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding) self.reshape_type_picker.setSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred) self.setLayout(self.layout) # Signals self.reshape_type_picker.itemSelectionChanged.connect(self.on_type_changed) self.dragger.finished.connect(self.on_dragger_finished) # Initial selection self.reshape_type_picker.setSelectionMode(QtWidgets.QAbstractItemView.SingleSelection) self.reshape_type_picker.setCurrentRow(0) self.on_type_changed()
def __init__(self, pgdf: PandasGuiDataFrame): super().__init__() pgdf = PandasGuiDataFrame.cast(pgdf) pgdf.dataframe_viewer = self self.pgdf = pgdf # Indicates whether the widget has been shown yet. Set to True in self._loaded = False # Set up DataFrame TableView and Model self.dataView = DataTableView(parent=self) # Create headers self.columnHeader = HeaderView(parent=self, orientation=Qt.Horizontal) self.indexHeader = HeaderView(parent=self, orientation=Qt.Vertical) self.columnHeaderNames = HeaderNamesView(parent=self, orientation=Qt.Horizontal) self.indexHeaderNames = HeaderNamesView(parent=self, orientation=Qt.Vertical) # Set up layout self.gridLayout = QtWidgets.QGridLayout() self.setLayout(self.gridLayout) # Link scrollbars # Scrolling in data table also scrolls the headers self.dataView.horizontalScrollBar().valueChanged.connect( self.columnHeader.horizontalScrollBar().setValue ) self.dataView.verticalScrollBar().valueChanged.connect( self.indexHeader.verticalScrollBar().setValue ) # Scrolling in headers also scrolls the data table self.columnHeader.horizontalScrollBar().valueChanged.connect( self.dataView.horizontalScrollBar().setValue ) self.indexHeader.verticalScrollBar().valueChanged.connect( self.dataView.verticalScrollBar().setValue ) self.dataView.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.dataView.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) # Disable scrolling on the headers. Even though the scrollbars are hidden, scrolling by dragging desyncs them self.indexHeader.horizontalScrollBar().valueChanged.connect(lambda: None) self.gridLayout.setContentsMargins(0, 0, 0, 0) self.gridLayout.setSpacing(0) # Add items to 4x4 grid layout self.gridLayout.addWidget(self.columnHeader, 0, 1, 1, 2) self.gridLayout.addWidget(self.indexHeader, 1, 0, 2, 2) self.gridLayout.addWidget(self.dataView, 2, 2, 1, 1) self.gridLayout.addWidget(self.dataView.horizontalScrollBar(), 3, 2, 1, 1) self.gridLayout.addWidget(self.dataView.verticalScrollBar(), 2, 3, 1, 1) self.gridLayout.addWidget(self.columnHeaderNames, 0, 3, 1, 1) self.gridLayout.addWidget(self.indexHeaderNames, 0, 0, 1, 1, Qt.AlignBottom) # These expand when the window is enlarged instead of having the grid squares spread out self.gridLayout.setColumnStretch(4, 1) self.gridLayout.setRowStretch(4, 1) self.gridLayout.addItem( QtWidgets.QSpacerItem(0, 0, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding), 0, 0, 1, 1, ) # Do this at top so sizeHints are calculated correctly self.set_styles() self.updateGeometry()