Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 34 additions & 8 deletions DataModel.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ class MatPlotModel(object):
def __init__(self, filename: str):
self.numeric_columns = []
self.string_columns = []
self.data = self.initFromData(filename)
self.raw_data = self.loadData(filename)
self.data = self.initFromData()
print(self.data)

def getMaterialFamily(self, key_name="Type"):
Expand All @@ -62,28 +63,53 @@ def getMaterialFamily(self, key_name="Type"):

def getItemByType(self, typestr: str):
return self.getItemsByFamily("Type", typestr)

def initFromData(self, filename: str):
def loadData(self, filename: str):
df = pd.DataFrame()
if filename:
temp_df = pd.read_csv(filename)
df = pd.read_csv(filename)
return df

def onRawDataUpdate(self):
self.data = self.initFromData()

def initFromData(self):
df = pd.DataFrame()
if len(self.raw_data) > 0:
# Find the numerical and string columns.
self.numeric_columns = list(temp_df.columns[temp_df.dtypes == np.float])
self.string_columns = list(temp_df.columns[temp_df.dtypes == np.dtype('O')])
self.numeric_columns = list(self.raw_data.columns[self.raw_data.dtypes == np.float])
self.string_columns = list(self.raw_data.columns[self.raw_data.dtypes == np.dtype('O')])
def groupData(df):
# Calculate the mean among all numeric columns.
avg_series = df.loc[:, self.numeric_columns].mean(axis=0, skipna=True)
# Take the first row to capture descriptive features in string columns.
avg_series = avg_series.append(df[self.string_columns].iloc[0].squeeze())
# avg_series = avg_series.append(df[self.string_columns].iloc[0].squeeze())
avg_series = pd.concat([df[self.string_columns].iloc[0].squeeze(), avg_series])
return avg_series
df = temp_df.groupby(temp_df.columns[0]).apply(groupData)
df = self.raw_data.groupby(self.raw_data.columns[0]).apply(groupData)
# Remove name from the string columns.
self.string_columns.remove("Name")

# Remove na for compatibility now!
df.dropna(inplace=True)
return df

def addMaterial(self):
pass

# TODO(team): handle more complex semantic expression.
def addProperty(self, new_column_info: List):
'''
Manipulate to calculate additional terms from the data. Return the name of the new term.
New column info is descried as [numerator, order_of_numerator, denominator, order_of_denominator].
'''
new_str = new_column_info[0] + '^' + str(new_column_info[1]) + '/' + new_column_info[2] + '^' + str(
new_column_info[3])
if new_str not in self.data.columns:
self.data[new_str] = (self.data[new_column_info[0]] ** new_column_info[1] / self.data[new_column_info[2]] **
new_column_info[3])
return new_str

def getStringColumns(self):
'''
Returns the candidate columns for users to select the family category.
Expand Down
70 changes: 70 additions & 0 deletions View/TableModel.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import pandas as pd
from PySide2.QtCore import QAbstractTableModel, QModelIndex, Qt


class TableModel(QAbstractTableModel):
def __init__(self, model):
super(TableModel, self).__init__()
self.model = model
self.hHeader = self.model.raw_data.columns.tolist()
# self.vHeader = self.data.index.tolist()

def rowCount(self, parent=QModelIndex()):
return self.model.raw_data.shape[0]

def columnCount(self, parent=QModelIndex()):
return self.model.raw_data.shape[1]

def data(self, index: QModelIndex, role=Qt.DisplayRole):
if not index.isValid():
return None
if role == Qt.TextAlignmentRole:
return Qt.AlignCenter
if role == Qt.DisplayRole:
return str(self.model.raw_data.iloc[index.row()][index.column()])
return None

def headerData(self, section, orientation, role):
if role != Qt.DisplayRole:
return None
if orientation == Qt.Horizontal:
return self.hHeader[section]
elif orientation == Qt.Vertical:
return section

def setData(self, index, value, role=Qt.EditRole):
row = index.row()
if index.isValid() and (0 <= row < self.rowCount()) and value:
col = index.column()
if 0 <= col < self.columnCount():
self.beginResetModel()
try:
dtype = type(self.model.raw_data.iloc[row, col])
self.model.raw_data.iloc[row, col] = dtype(value)
except Exception:
dtype = type(self.model.raw_data.iloc[row-1, col])
self.model.raw_data.iloc[row, col] = dtype(value)
self.model.onRawDataUpdate()
self.dirty = True
self.endResetModel()
return True
return False


def insertRows(self, position=-1, rows=1, index=QModelIndex()):
position = self.rowCount()
if position > 0:
self.beginInsertRows(QModelIndex(), position, position+rows-1)
self.model.raw_data = pd.concat([self.model.raw_data, pd.DataFrame([[pd.NA]*self.columnCount()], columns=self.model.raw_data.columns)])
self.endInsertRows()
self.dirty = True
return True
return False

def deleteRows(self):
pass

def flags(self, index):
if not index.isValid():
return Qt.ItemIsEnabled
return Qt.ItemFlags(QAbstractTableModel.flags(self, index)|Qt.ItemIsEditable|Qt.ItemIsSelectable)
30 changes: 30 additions & 0 deletions View/TableWidget.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
from PySide2.QtCore import Qt, QAbstractTableModel, QFile
from PySide2.QtUiTools import QUiLoader
from PySide2.QtWidgets import QWidget, QHBoxLayout, QVBoxLayout, QTableView, QPushButton
from View.TableModel import TableModel

class ManageItem(QWidget):
def __init__(self, model):
super(ManageItem, self).__init__()

layout0 = QVBoxLayout()
layout1 = QHBoxLayout()
self.addButton = QPushButton("Add Item")
self.deleteButton = QPushButton("Delete Item")
layout1.addWidget(self.addButton)
layout1.addWidget(self.deleteButton)

self.tableModel = TableModel(model)
self.table = QTableView()
self.table.setModel(self.tableModel)
self.table.resizeColumnsToContents()
self.table.resizeRowsToContents()
layout2 = QHBoxLayout()
layout2.addWidget(self.table)
layout0.addLayout(layout1)
layout0.addLayout(layout2)

self.setLayout(layout0)
self.resize(1200, 800)

self.addButton.clicked.connect(self.tableModel.insertRows)
7 changes: 7 additions & 0 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from GraphicsModule import MatPlotController
from View.AGraphicsView import AGraphicsView
from View.TreeView import TreeView
from View.TableWidget import ManageItem

app = None

Expand Down Expand Up @@ -49,6 +50,7 @@ def connectSignals(self):
self.ui.actionResetView.triggered.connect(self.onResetView)
self.ui.actionFitView.triggered.connect(self.onFitView)
self.ui.actionAxes.triggered.connect(self.onDefineAxes)
self.ui.actionManageItem.triggered.connect(self.onManageItem)
self.ui.actionCapture.triggered.connect(self.onActionCapture)

## top layer of buttons ##
Expand Down Expand Up @@ -184,6 +186,11 @@ def onActionFamilyHull(self):

def onRefreshTreeList(self):
self.controller.initTreeView(self.ui.familyColumn.currentText())

def onManageItem(self):
self.manager = ManageItem(self.controller.model)
self.manager.show()


class setAxesPopUp(QDialog):
def __init__(self, column_candidates: List[str]):
Expand Down
6 changes: 5 additions & 1 deletion matplot.ui
Original file line number Diff line number Diff line change
Expand Up @@ -608,7 +608,7 @@
<x>0</x>
<y>0</y>
<width>1616</width>
<height>23</height>
<height>22</height>
</rect>
</property>
<widget class="QMenu" name="menuFile">
Expand Down Expand Up @@ -710,6 +710,7 @@
<addaction name="actionAxes"/>
<addaction name="actionResetView"/>
<addaction name="actionFitView"/>
<addaction name="actionManageItem"/>
<addaction name="separator"/>
<addaction name="actionOpen_CSV"/>
<addaction name="actionFamily"/>
Expand Down Expand Up @@ -874,6 +875,9 @@
<string>FitView</string>
</property>
</action>
<action name="actionManageItem">
<property name="text">
<string>ManageItem</string>
<action name="actionCapture">
<property name="text">
<string>Capture...</string>
Expand Down