#!/usr/bin/env python
# coding: utf-8
import pyqtgraph as pg
from pyqtgraph.Qt import QtGui
from pyqtgraph.Qt import QtCore
import numpy as np
import pandas as pd # required for estimation graph
from .. import stm_df
"""
=============
График виӝет
Grafy
Estimation graph widgets
========================
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
"""
def get_estimation_data(estimations, metric):
metric_dict = dict()
# new-style: šecko leží dohromady a každý z toho
# bere co chce a jak chce
# ne že by to bylo nějak šetrný
# estimation je slovníkem
for estimation in estimations:
# nsim musí mäť každej odhad
# pokud nemá - je třeba jej prostě opravit
nsim = estimation['nsim']
try:
metric_dict[nsim] = estimation[metric]
except KeyError as e:
pass #print(self.__class__.__name__ + ":", repr(e))
# nikdo neslibil, že budou v pořadí
x = np.sort(tuple(metric_dict.keys()))
y = np.array(tuple(metric_dict.values()))[np.argsort(tuple(metric_dict.keys()))]
return x, y
class SimplexEstimationData(QtCore.QObject):
#š budeme mӓť svůj vlastní signaľčík
simplex_estimation_updated = QtCore.pyqtSignal()
def __init__(self, dice_box, stream=None, *args, **kwargs):
super().__init__(stream, *args, **kwargs)
self.dice_box = dice_box
#č je zřejmě, že tím potokem bylo myšleno hlavní okínko
#č asi aby nepadalo, když nenajde signaly
self.stream = stream
if stream is not None:
self.stream.box_runned.connect(self.recalculate)
self.stream.estimation_added.connect(self.recalculate)
self.setup_context_menu()
self.recalculate()
def setup_context_menu(self):
# simplex_data_menu
self.TRI_menu = QtGui.QMenu("TRI sources", self.stream)
self.TRI_overall_chk = QtGui.QAction("TRI_overall_estimations", self.TRI_menu)
self.TRI_overall_chk.setCheckable(True)
self.TRI_overall_chk.setChecked(True)
self.TRI_overall_chk.triggered.connect(self.recalculate)
self.TRI_menu.addAction(self.TRI_overall_chk)
self.simplex_chk = QtGui.QAction("Simplex estimations", self.TRI_menu)
self.simplex_chk.setCheckable(True)
self.simplex_chk.setChecked(True)
self.simplex_chk.triggered.connect(self.recalculate)
self.TRI_menu.addAction(self.simplex_chk)
# year, it was
## hope, it is temporary
#self.sources_action_group = QtGui.QActionGroup(self.TRI_menu)
#self.sources_action_group.addAction(self.TRI_overall_chk)
#self.sources_action_group.addAction(self.simplex_chk)
self.TRI_menu.addSeparator()
self.proxy_chk = QtGui.QAction("Proxy", self.TRI_menu)
self.proxy_chk.setCheckable(True)
self.proxy_chk.setChecked(hasattr(self.dice_box, 'proxy'))
self.proxy_chk.triggered.connect(self.recalculate)
self.TRI_menu.addAction(self.proxy_chk)
self.TRI_menu.addSeparator()
self.reaction = QtGui.QAction("Update", self.TRI_menu)
self.reaction.triggered.connect(self.recalculate)
self.TRI_menu.addAction(self.reaction)
self.excelaction = QtGui.QAction("Export to Excel", self.TRI_menu)
self.excelaction.triggered.connect(self.export_to_excel)
self.TRI_menu.addAction(self.excelaction)
def export_to_excel(self):
#č já bych nechtěl, aby mně export najednou spadl
#č z jakéhokoliv důvodu
try:
proposal_filename = self.dice_box.guessbox.filename
if proposal_filename:
proposal_filename += '.xlsx'
else:
proposal_filename = self.dice_box.gm_signature + '.xlsx'
filename, *__ = pg.FileDialog.getSaveFileName(self.stream, 'Export to Excel',\
proposal_filename, initialFilter='*.xlsx')
self.df.to_excel(filename)
except BaseException as e:
print(self.__class__.__name__ + ":", repr(e))
def recalculate(self):
try:
# sources=['box', 'user']
sources = list()
if self.TRI_overall_chk.isChecked():
sources.append('box')
if self.simplex_chk.isChecked():
sources.append('user')
self.df = stm_df.get_tri_data_frame(self.dice_box, sources=sources,\
apply_proxy=self.proxy_chk.isChecked())
self.simplex_estimation_updated.emit()
except BaseException as e:
print(self.__class__.__name__ + ":", repr(e))
class SimplexEstimationGraph(pg.PlotWidget):
def __init__(self, dice_box, stream=None, parent=None, *args, **kwargs):
super().__init__(parent, *args, **kwargs)
#č je zřejmě, že tím potokem bylo myšleno hlavní okínko
#č asi aby nepadalo, když nenajde signaly
self.stream = stream
if stream is not None:
self.stream.box_runned.connect(self.redraw)
self.stream.estimation_added.connect(self.redraw)
self.dice_box = dice_box
self.setup_context_menu()
self.setup()
self.replot()
def setup_context_menu(self):
# creates instance of LegendItem
# and saves it into plotItem.legend
self.legend = self.addLegend()
self.plotItem.ctrl.xGridCheck.setChecked(True)
self.plotItem.ctrl.yGridCheck.setChecked(True)
# delete build-in Transforms (with Log_x and Log_y) options,
# they can cause uncachable exception (on any zero in data) and crash
self.plotItem.ctrlMenu.removeAction(self.plotItem.ctrlMenu.actions()[0])
#č já se bojím. radší to uložím
self.custom_menu = self.plotItem.vb.menu.addMenu("TRI options")
self.plotItem.vb.menu.addMenu(self.stream.simplex_data.TRI_menu)
self.legend_chk = QtGui.QAction("Legend", self.custom_menu)
self.legend_chk.setCheckable(True)
self.legend_chk.triggered.connect(lambda: self.legend.setVisible(self.legend_chk.isChecked()))
self.custom_menu.addAction(self.legend_chk)
# apply custom menu option
self.legend.setVisible(self.legend_chk.isChecked())
self.log_x_chk = QtGui.QAction("Log X", self.custom_menu)
self.log_x_chk.setCheckable(True)
self.log_x_chk.triggered.connect(lambda: self.setLogMode(x=self.log_x_chk.isChecked()))
self.custom_menu.addAction(self.log_x_chk)
self.log_y_chk = QtGui.QAction("Log Y", self.custom_menu)
self.log_y_chk.setCheckable(True)
self.log_y_chk.setChecked(True)
self.log_y_chk.triggered.connect(self.replot)
self.custom_menu.addAction(self.log_y_chk)
self.laction = QtGui.QAction("Show labels", self.custom_menu)
self.laction.triggered.connect(self.show_labels)
self.custom_menu.addAction(self.laction)
def show_labels(self):
self.setLabel('left', "Probability measure")
self.setLabel('bottom', "Number of simulations")
# self.legend.addItem(self.pen_success, "success domain estimation")
# self.legend.addItem(self.pen_outside, "out of sampling domain estimation")
# self.legend.addItem(self.pen_mix, "mixed simplices measure")
# self.legend.addItem(self.pen_f, "failure domain estimation")
def setup(self, *args, **kwargs):
self.clear()
self.setBackground('w')
x = y = () # zde jen vytvoříme kostru, nakrmime daty v .redraw()
#xkcd_green = (167, 255, 181) # xkcd:light seafoam green #a7ffb5
green = (0, 255, 38, 96)
#xkcd_red = (253, 193, 197) # xkcd: pale rose (#fdc1c5)
red = (253, 0, 17, 96)
#xkcd_cream = (255, 243, 154) # let's try xkcd: dark cream (#fff39a)
cream = (255, 221, 0, 96)
grey = (196, 196, 196, 96)
self.pen_f = self.plot(x, y, brush=red)#, name="failure domain estimation")
self.pen_f.setZValue(-100)
self.pen_success = self.plot(x, y, brush=green) #, name="success domain estimation")
self.pen_success.setZValue(-100)
self.pen_outmix = self.plot(x, y)
self.fill_mix = pg.FillBetweenItem(self.pen_f, self.pen_outmix)
#self.fill_mix.setData(name="mixed simplices measure")
self.fill_mix.setBrush(cream)
self.fill_mix.setZValue(-100)
self.addItem(self.fill_mix)
#self.pen_outside = self.plot(x, y)
self.fill_outside = pg.FillBetweenItem(self.pen_outmix, self.pen_success)
#self.fill_outside.setData(name="out of sampling domain estimation")
self.fill_outside.setBrush(grey)
self.fill_outside.setZValue(-100)
self.addItem(self.fill_outside)
self.one_ruler = self.addLine(y=1, pen='k')
self.zero_ruler = self.addLine(y=0, pen='k')
try:
exact_name = self.dice_box.pf_exact_method
pen = pg.mkPen(color='b', width=1.5) # blue
self.pen_exact = self.addLine(y=self.dice_box.pf_exact, pen=pen, name=exact_name)
#č aby se nám něco zobrazovalo v legendu
self.pen_exact_PR = self.plot(x, y, pen=pen, name=exact_name)
except:
pass
pen = pg.mkPen(color='m', width=2)
self.pen_vertex = self.plot(x, y, pen=pen, name="simple pf estimation")
pen = pg.mkPen(color='r', width=2) #(118, 187, 255)
self.pen_weighted_vertex = self.plot(x, y, pen=pen, name="weighted pf estimation")
def replot(self, *args, **kwargs):
if self.log_y_chk.isChecked():
self.one_ruler.hide()
try:
#č try nás nezáchraní protí odloženému spádnutí pyqtgraph
if self.dice_box.pf_exact > 0:
self.pen_exact.setPos(np.log10(self.dice_box.pf_exact))
self.pen_exact.show()
else:
self.pen_exact.hide()
except:
pass
self.setLogMode(y=True)
#self.pen_f.setPen(pg.mkPen(color=(255, 0, 0), width=3)) #, style=QtCore.Qt.DashLine)
self.pen_f.setPen(None)
self.pen_f.setFillLevel(None)
self.pen_success.setFillLevel(0)
else:
self.one_ruler.show()
try:
self.pen_exact.setPos(self.dice_box.pf_exact)
self.pen_exact.show()
except:
pass
self.setLogMode(y=False)
self.pen_f.setPen(None)
self.pen_f.setFillLevel(0)
self.pen_success.setFillLevel(1)
self.redraw()
#č když se někde objeví nula se zapnutým LogModem -
#č qtpygraph hned spadne a není možne ten pad zachytit
def zerosafe(self, x, y, fallback_y=None):
if self.log_y_chk.isChecked():
x = np.array(x)
y = np.array(y)
if fallback_y is None:
fallback_y = y
y = np.where(y > 0, y, fallback_y)
mask = y > 0
return x[mask], y[mask]
else:
return x, y
def proxy(self, nsim):
if self.proxy_chk.isChecked():
proxy = self.dice_box.proxy
index = np.array(nsim)-1
#č indexy musíme o jedničku změnšit
#č výsledek nikoliv. Takže v cajku.
return np.cumsum(~proxy)[index]
else:
return nsim
def _pens_data_update(self):
df = self.df
nsim = df.nsim.to_numpy()
if self.proxy_chk.isChecked():
x = self.proxy(nsim)
df.insert(loc=0, column='nsim (proxy)', value=x)
else:
x = nsim
# (in case of LogPlot) fallback values also used
success_values = df.failure+df.mix+df.out
outmix_values = df.failure+df.mix
failure_fallback = np.where(outmix_values > 0, outmix_values, success_values)
self.pen_f.setData(*self.zerosafe(x, df.failure, failure_fallback))
self.pen_outmix.setData(*self.zerosafe(x, outmix_values, success_values))
self.pen_success.setData(*self.zerosafe(x, success_values))
def redraw(self):
xmin = np.inf
xmax = -np.inf
tri_estimation = dict()
try: # тут всё что угодно может пойти не так
# kruci, ještě navic i generovať pokažde znovu...
# new-style: šecko leží dohromady a každý si z toho
# bere co chce a jak chce
# ne že by to bylo nějak šetrný
# estimation je slovníkem
for estimation in self.dice_box.estimations:
# nsim musí mäť každej odhad
# pokud nemá - je třeba jej prostě opravit
nsim = estimation['nsim']
try:
tri_estimation[nsim] = estimation['TRI_estimation']
if nsim > xmax:
xmax = nsim
if nsim < xmin:
xmin = nsim
except KeyError as e:
pass #print(self.__class__.__name__ + ":", repr(e))
#č neotravuj uživatele chybovejma hlaškama
if tri_estimation:
# it can be effectively done with pandas
self.df = df = pd.DataFrame(tuple(tri_estimation.values()))
# -1 = 'out', 0=success, 1=failure, 2=mix
df.rename(columns={-1:'out', 0:'success', 1:'failure', 2:'mix'}, inplace=True)
df.insert(loc=0, column='nsim', value=tuple(tri_estimation.keys()), allow_duplicates=False)
df.sort_values('nsim', inplace=True)
self._pens_data_update()
nsim, y = get_estimation_data(self.dice_box.estimations, 'vertex_estimation')
df['vertex_estimation'] = y #č spolehám na konzistenci odhadů (ne úplně)
self.pen_vertex.setData(*self.zerosafe(self.proxy(nsim), y))
nsim, y = get_estimation_data(self.dice_box.estimations, 'weighted_vertex_estimation')
df['weighted_vertex_estimation'] = y #č spolehám na konzistenci odhadů (ne úplně)
self.pen_weighted_vertex.setData(*self.zerosafe(self.proxy(nsim), y))
except BaseException as e:
print(self.__class__.__name__ + ":", repr(e))
class SimplexErrorGraph(pg.PlotWidget):
def __init__(self, simplex_data, parent=None, *args, **kwargs):
super().__init__(parent, *args, **kwargs)
self.simplex_data = simplex_data
self.simplex_data.simplex_estimation_updated.connect(self.redraw)
self.setup_context_menu()
self.setup()
def setup_context_menu(self):
# creates instance of LegendItem
# and saves it into plotItem.legend
self.legend = self.addLegend()
self.plotItem.ctrl.xGridCheck.setChecked(True)
self.plotItem.ctrl.yGridCheck.setChecked(True)
# menu of SimplexEstimationData
self.plotItem.vb.menu.addMenu(self.simplex_data.TRI_menu)
#č já se bojím. radší to uložím
self.custom_menu = self.plotItem.vb.menu.addMenu("Error graph")
self.legend_chk = QtGui.QAction("Legend", self.custom_menu)
self.legend_chk.setCheckable(True)
self.legend_chk.triggered.connect(lambda: self.legend.setVisible(self.legend_chk.isChecked()))
self.custom_menu.addAction(self.legend_chk)
# apply custom menu option
self.legend.setVisible(self.legend_chk.isChecked())
self.laction = QtGui.QAction("Show labels", self.custom_menu)
self.laction.triggered.connect(self.show_labels)
self.custom_menu.addAction(self.laction)
def show_labels(self):
self.setLabel('left', "Failure probability estimation error")
self.setLabel('bottom', "Number of simulations")
def setup(self, *args, **kwargs):
self.clear()
self.setBackground('w')
x = y = () # zde jen vytvoříme kostru, nakrmime daty v .redraw()
# We will use logMode by default
self.setLogMode(y=True)
#xkcd_red = (253, 193, 197) # xkcd: pale rose (#fdc1c5)
#red = (253, 0, 17, 96)
#self.pen_f = self.plot(x, y, brush=red)#, name="failure domain estimation")
#self.pen_f.setZValue(-100)
pen = pg.mkPen(color='m', width=2)
self.pen_vertex = self.plot(x, y, pen=pen, name="simple pf estimation")
pen = pg.mkPen(color='r', width=2) #(118, 187, 255)
self.pen_weighted_vertex = self.plot(x, y, pen=pen, name="weighted pf estimation")
#č když se někde objeví nula se zapnutým LogModem -
#č qtpygraph hned spadne a není možne ten pad zachytit
def zerosafe(self, x, y, fallback_y=None):
x = np.array(x)
y = np.array(y)
if fallback_y is None:
fallback_y = y
y = np.where(y > 0, y, fallback_y)
mask = y > 0
return x[mask], y[mask]
def redraw(self):
#č neotravujme uživatele chybovejma hlaškama
if hasattr(self.simplex_data.dice_box, 'pf_exact'):
try: #ё тут всё что угодно может пойти не так
pf_exact = self.simplex_data.dice_box.pf_exact
df = self.simplex_data.df
#č zapíšeme do data rámu, snad nikomu nebude vadit
df['vertex_estimation_error'] = df['vertex_estimation'] - pf_exact
df['weighted_vertex_estimation_error'] = df['weighted_vertex_estimation'] - pf_exact
v = df['vertex_estimation_error'].abs()
wv = df['weighted_vertex_estimation_error'].abs()
x, y = self.zerosafe(v.index, v.to_numpy())
self.pen_vertex.setData(x, y)
x, y = self.zerosafe(wv.index, wv.to_numpy())
self.pen_weighted_vertex.setData(x, y)
except BaseException as e:
print(self.__class__.__name__ + ":", repr(e))
# DEPRECATED
class SimpleSimplexEstimationGraph(pg.PlotWidget):
def __init__(self, dice_box, stream=None, parent=None, *args, **kwargs):
super().__init__(parent, *args, **kwargs)
#č je zřejmě, že tím potokem bylo myšleno hlavní okínko
#č asi aby nepadalo, když nenajde signaly
self.stream = stream
if stream is not None:
self.stream.box_runned.connect(self.redraw)
self.stream.estimation_added.connect(self.redraw)
self.dice_box = dice_box
self.setup_context_menu()
self.setup()
self.replot()
def setup_context_menu(self):
# creates instance of LegendItem
# and saves it into plotItem.legend
self.legend = self.addLegend()
self.plotItem.ctrl.xGridCheck.setChecked(True)
self.plotItem.ctrl.yGridCheck.setChecked(True)
# delete build-in Transforms (with Log_x and Log_y) options,
# they can cause uncachable exception (on any zero in data) and crash
self.plotItem.ctrlMenu.removeAction(self.plotItem.ctrlMenu.actions()[0])
#č já se bojím. radší to uložím
self.custom_menu = self.plotItem.vb.menu.addMenu("TRI options")
self.legend_chk = QtGui.QAction("Legend", self.custom_menu)
self.legend_chk.setCheckable(True)
self.legend_chk.triggered.connect(lambda: self.legend.setVisible(self.legend_chk.isChecked()))
self.custom_menu.addAction(self.legend_chk)
# apply custom menu option
self.legend.setVisible(self.legend_chk.isChecked())
self.proxy_chk = QtGui.QAction("Proxy", self.custom_menu)
self.proxy_chk.setCheckable(True)
self.proxy_chk.triggered.connect(self.redraw)
self.custom_menu.addAction(self.proxy_chk)
self.log_x_chk = QtGui.QAction("Log X", self.custom_menu)
self.log_x_chk.setCheckable(True)
self.log_x_chk.triggered.connect(lambda: self.setLogMode(x=self.log_x_chk.isChecked()))
self.custom_menu.addAction(self.log_x_chk)
self.log_y_chk = QtGui.QAction("Log Y", self.custom_menu)
self.log_y_chk.setCheckable(True)
self.log_y_chk.setChecked(True)
self.log_y_chk.triggered.connect(self.replot)
self.custom_menu.addAction(self.log_y_chk)
self.reaction = QtGui.QAction("Redraw", self.custom_menu)
self.reaction.triggered.connect(self.redraw)
self.custom_menu.addAction(self.reaction)
self.laction = QtGui.QAction("Show labels", self.custom_menu)
self.laction.triggered.connect(self.show_labels)
self.custom_menu.addAction(self.laction)
self.excelaction = QtGui.QAction("Export to Excel", self.custom_menu)
self.excelaction.triggered.connect(self.export_to_excel)
self.custom_menu.addAction(self.excelaction)
def export_to_excel(self):
#č já bych nechtěl, aby mně export najednou spadl
#č z jakéhokoliv důvodu
try:
proposal_filename = self.dice_box.guessbox.filename
if proposal_filename:
proposal_filename += '.xlsx'
else:
proposal_filename = self.dice_box.gm_signature + '.xlsx'
filename, *__ = pg.FileDialog.getSaveFileName(self, 'Export to Excel',\
proposal_filename, initialFilter='*.xlsx')
self.df.to_excel(filename)
except BaseException as e:
print(self.__class__.__name__ + ":", repr(e))
def show_labels(self):
self.setLabel('left', "Probability measure")
self.setLabel('bottom', "Number of simulations")
# self.legend.addItem(self.pen_success, "success domain estimation")
# self.legend.addItem(self.pen_outside, "out of sampling domain estimation")
# self.legend.addItem(self.pen_mix, "mixed simplices measure")
# self.legend.addItem(self.pen_f, "failure domain estimation")
def setup(self, *args, **kwargs):
self.clear()
self.setBackground('w')
x = y = () # zde jen vytvoříme kostru, nakrmime daty v .redraw()
#xkcd_green = (167, 255, 181) # xkcd:light seafoam green #a7ffb5
green = (0, 255, 38, 96)
#xkcd_red = (253, 193, 197) # xkcd: pale rose (#fdc1c5)
red = (253, 0, 17, 96)
#xkcd_cream = (255, 243, 154) # let's try xkcd: dark cream (#fff39a)
cream = (255, 221, 0, 96)
grey = (196, 196, 196, 96)
self.pen_f = self.plot(x, y, brush=red)#, name="failure domain estimation")
self.pen_f.setZValue(-100)
self.pen_success = self.plot(x, y, brush=green) #, name="success domain estimation")
self.pen_success.setZValue(-100)
self.pen_outmix = self.plot(x, y)
self.fill_mix = pg.FillBetweenItem(self.pen_f, self.pen_outmix)
#self.fill_mix.setData(name="mixed simplices measure")
self.fill_mix.setBrush(cream)
self.fill_mix.setZValue(-100)
self.addItem(self.fill_mix)
#self.pen_outside = self.plot(x, y)
self.fill_outside = pg.FillBetweenItem(self.pen_outmix, self.pen_success)
#self.fill_outside.setData(name="out of sampling domain estimation")
self.fill_outside.setBrush(grey)
self.fill_outside.setZValue(-100)
self.addItem(self.fill_outside)
self.one_ruler = self.addLine(y=1, pen='k')
self.zero_ruler = self.addLine(y=0, pen='k')
try:
exact_name = self.dice_box.pf_exact_method
pen = pg.mkPen(color='b', width=1.5) # blue
self.pen_exact = self.addLine(y=self.dice_box.pf_exact, pen=pen, name=exact_name)
#č aby se nám něco zobrazovalo v legendu
self.pen_exact_PR = self.plot(x, y, pen=pen, name=exact_name)
except:
pass
pen = pg.mkPen(color='m', width=2)
self.pen_vertex = self.plot(x, y, pen=pen, name="simple pf estimation")
pen = pg.mkPen(color='r', width=2) #(118, 187, 255)
self.pen_weighted_vertex = self.plot(x, y, pen=pen, name="weighted pf estimation")
def replot(self, *args, **kwargs):
if self.log_y_chk.isChecked():
self.one_ruler.hide()
try:
#č try nás nezáchraní protí odloženému spádnutí pyqtgraph
if self.dice_box.pf_exact > 0:
self.pen_exact.setPos(np.log10(self.dice_box.pf_exact))
self.pen_exact.show()
else:
self.pen_exact.hide()
except:
pass
self.setLogMode(y=True)
#self.pen_f.setPen(pg.mkPen(color=(255, 0, 0), width=3)) #, style=QtCore.Qt.DashLine)
self.pen_f.setPen(None)
self.pen_f.setFillLevel(None)
self.pen_success.setFillLevel(0)
else:
self.one_ruler.show()
try:
self.pen_exact.setPos(self.dice_box.pf_exact)
self.pen_exact.show()
except:
pass
self.setLogMode(y=False)
self.pen_f.setPen(None)
self.pen_f.setFillLevel(0)
self.pen_success.setFillLevel(1)
self.redraw()
#č když se někde objeví nula se zapnutým LogModem -
#č qtpygraph hned spadne a není možne ten pad zachytit
def zerosafe(self, x, y, fallback_y=None):
if self.log_y_chk.isChecked():
x = np.array(x)
y = np.array(y)
if fallback_y is None:
fallback_y = y
y = np.where(y > 0, y, fallback_y)
mask = y > 0
return x[mask], y[mask]
else:
return x, y
def proxy(self, nsim):
if self.proxy_chk.isChecked():
proxy = self.dice_box.proxy
index = np.array(nsim)-1
#č indexy musíme o jedničku změnšit
#č výsledek nikoliv. Takže v cajku.
return np.cumsum(~proxy)[index]
else:
return nsim
def _pens_data_update(self):
df = self.df
nsim = df.nsim.to_numpy()
if self.proxy_chk.isChecked():
x = self.proxy(nsim)
df.insert(loc=0, column='nsim (proxy)', value=x)
else:
x = nsim
# (in case of LogPlot) fallback values also used
success_values = df.failure+df.mix+df.out
outmix_values = df.failure+df.mix
failure_fallback = np.where(outmix_values > 0, outmix_values, success_values)
self.pen_f.setData(*self.zerosafe(x, df.failure, failure_fallback))
self.pen_outmix.setData(*self.zerosafe(x, outmix_values, success_values))
self.pen_success.setData(*self.zerosafe(x, success_values))
def redraw(self):
xmin = np.inf
xmax = -np.inf
tri_estimation = dict()
try: # тут всё что угодно может пойти не так
# kruci, ještě navic i generovať pokažde znovu...
# new-style: šecko leží dohromady a každý si z toho
# bere co chce a jak chce
# ne že by to bylo nějak šetrný
# estimation je slovníkem
for estimation in self.dice_box.estimations:
# nsim musí mäť každej odhad
# pokud nemá - je třeba jej prostě opravit
nsim = estimation['nsim']
try:
tri_estimation[nsim] = estimation['TRI_estimation']
if nsim > xmax:
xmax = nsim
if nsim < xmin:
xmin = nsim
except KeyError as e:
pass #print(self.__class__.__name__ + ":", repr(e))
#č neotravuj uživatele chybovejma hlaškama
if tri_estimation:
# it can be effectively done with pandas
self.df = df = pd.DataFrame(tuple(tri_estimation.values()))
# -1 = 'out', 0=success, 1=failure, 2=mix
df.rename(columns={-1:'out', 0:'success', 1:'failure', 2:'mix'}, inplace=True)
df.insert(loc=0, column='nsim', value=tuple(tri_estimation.keys()), allow_duplicates=False)
df.sort_values('nsim', inplace=True)
self._pens_data_update()
nsim, y = get_estimation_data(self.dice_box.estimations, 'vertex_estimation')
df['vertex_estimation'] = y #č spolehám na konzistenci odhadů (ne úplně)
self.pen_vertex.setData(*self.zerosafe(self.proxy(nsim), y))
nsim, y = get_estimation_data(self.dice_box.estimations, 'weighted_vertex_estimation')
df['weighted_vertex_estimation'] = y #č spolehám na konzistenci odhadů (ne úplně)
self.pen_weighted_vertex.setData(*self.zerosafe(self.proxy(nsim), y))
except BaseException as e:
print(self.__class__.__name__ + ":", repr(e))
# DEPRECATED
class TriEstimationGraph(SimpleSimplexEstimationGraph):
def __init__(self, dice_box, tri_estimation_name='TRI_overall_estimations', stream=None, parent=None, *args, **kwargs):
self.tri_estimation_name = tri_estimation_name
super().__init__(dice_box, stream, parent, *args, **kwargs)
def redraw(self):
try: # тут всё что угодно может пойти не так
data = self.dice_box.guessbox.estimations[self.tri_estimation_name]
nsim, tri_data = data
# it can be effectively done with pandas
self.df = df = pd.DataFrame(tri_data)
# -1 = 'out', 0=success, 1=failure, 2=mix
df.rename(columns={-1:'out', 0:'success', 1:'failure', 2:'mix'}, inplace=True)
df.insert(loc=0, column='nsim', value=nsim)
# Update the data
self._pens_data_update()
if 'vertex_estimation' in self.dice_box.guessbox.estimations:
data = self.dice_box.guessbox.estimations['vertex_estimation']
nsim, y = data
# Update the data
#č spolehám na konzistenci blackboxu, ne však úplně
self.pen_vertex.setData(*self.zerosafe(self.proxy(nsim), np.array(y)))
df['vertex_estimation'] = y
if 'weighted_vertex_estimation' in self.dice_box.guessbox.estimations:
data = self.dice_box.guessbox.estimations['weighted_vertex_estimation']
nsim, y = data
# Update the data
#č spolehám na konzistenci blackboxu, ne však úplně
self.pen_weighted_vertex.setData(*self.zerosafe(self.proxy(nsim), np.array(y)))
df['weighted_vertex_estimation'] = y
# BaseException
except BaseException as e:
print(self.__class__.__name__ + ":", repr(e))
class VoronoiEstimationGraph(pg.PlotWidget):
def __init__(self, black_box, samplebox_item, parent=None, *args, **kwargs):
super().__init__(parent)
self.sb_item = samplebox_item
self.sb_item.box_runned.connect(self.redraw)
self.sb_item.estimation_added.connect(self.redraw)
self.black_box = black_box
self.setBackground('w')
self.reaction = QtGui.QAction("Redraw", self.plotItem.ctrlMenu)
self.reaction.triggered.connect(self.redraw)
self.plotItem.ctrlMenu.insertAction(self.plotItem.ctrlMenu.actions()[0], self.reaction)
# implicitně Y je v logaritmickem měřítku
self.setLogMode(False, True)
x = y = () # zde jen vytvoříme kostru, nakrmíme daty v .redraw()
# nechapu, proč těm Itemům ríkám "propíska"
# propíska? Их есть у нас!
self.Voronoi_2_point_upper_bound = self.plot(x, y, pen='y')
self.Voronoi_2_point_lower_bound = self.plot(x, y, pen='y')
fill_color = (255, 243, 154) # let's try xkcd: dark cream (#fff39a)
self.fill = pg.FillBetweenItem(self.Voronoi_2_point_upper_bound, self.Voronoi_2_point_lower_bound, fill_color)
self.addItem(self.fill)
self.Voronoi_2_point_failure_rate = self.plot(x, y, pen=(195,46,212))
self.Voronoi_2_point_pure_failure_rate = self.plot(x, y, pen='m')
self.Voronoi_failure_rate = self.plot(x, y, pen='r')
self.pen_exact = self.plot(x, y, pen='b') # blue
self.pen_one = self.plot(x, y, pen='k') # black
self.redraw()
def redraw(self):
# kruci, ještě navic i generovať pokažde znovu...
metrics = {'Voronoi_2_point_upper_bound':{},\
'Voronoi_2_point_lower_bound':{},\
'Voronoi_2_point_failure_rate':{},\
'Voronoi_2_point_pure_failure_rate':{},\
'Voronoi_failure_rate':{},}
xmin = np.inf
xmax = -np.inf
try: # тут всё что угодно может пойти не так
# new-style: šecko leží dohromady a každý z toho
# bere co chce a jak chce
# ne že by to bylo nějak šetrný
# estimation je slovníkem
for estimation in self.black_box.estimations:
# nsim musí mäť každej odhad
# pokud nemá - je třeba jej prostě opravit
nsim = estimation['nsim']
for metric, metric_dict in metrics.items():
try:
if estimation[metric] > 0:
metric_dict[nsim] = estimation[metric]
if nsim > xmax:
xmax = nsim
if nsim < xmin:
xmin = nsim
except KeyError as e:
pass #print(self.__class__.__name__ + ":", repr(e))
for metric, metric_dict in metrics.items():
pen = getattr(self, metric)
# nikdo neslibil, že budou v pořadí
x = np.sort(tuple(metric_dict.keys()))
y = np.array(tuple(metric_dict.values()))[np.argsort(tuple(metric_dict.keys()))]
pen.setData(x, y)
if (xmax - xmin) > 0:
self.pen_one.setData((xmin,xmax), (1, 1))
if hasattr(self.black_box, 'pf_exact'):
# poslední. I když spadne, tak už nikomu moc nevadí
self.pen_exact.setData((xmin,xmax), (self.black_box.pf_exact, self.black_box.pf_exact))
except BaseException as e:
print(self.__class__.__name__ + ":", repr(e))
# pen_f.opts['logMode']
# pen_outside.setLogMode(False, False)
#setLogMode(False, False)
#f = pg.FillBetweenItem(curves[i], curves[i+1], brushes[i])
#win.addItem(f)