Efficiency-Agent / src /ui /graphs /tools_graphs.py
mriusero
feat: general metrics
f731ddb
import gradio as gr
import numpy as np
import plotly.graph_objects as go
from scipy.stats import norm
class ToolMetricsDisplay:
def __init__(self):
self.df = None
self.pos_color = '#2CFCFF'
self.ori_color = '#ff8508'
self.plots = []
@staticmethod
def gauge(df, type=None, cote=None):
width = 205
height = 150
margin = dict(l=30, r=50, t=50, b=0)
if df is None or df.empty:
fig = go.Figure()
fig.update_layout(
template='plotly_dark',
width=width,
height=height,
margin=margin,
annotations=[dict(
text="No data",
showarrow=False,
font=dict(size=16, color="white")
)]
)
return fig
column = f"{cote}_rolling_{type}"
idx = df['Timestamp'].idxmax()
value = df.loc[idx, column]
fig = go.Figure(go.Indicator(
mode="gauge+number",
value=value,
number={'font': {'color': 'white', 'size': 20}},
domain={'x': [0, 1], 'y': [0, 1]},
title={'text': type, 'font': {'color': 'white', 'size': 16}},
gauge={'axis': {'range': [0, 3]},
'bar': {'color': 'black', 'thickness': 0.4},
'steps': [
{'range': [0, 1.33], 'color': "red"},
{'range': [1.33, 2], 'color': "yellow"},
{'range': [2, 3], 'color': "green"}],
'threshold': {
'line': {'color': 'black', 'width': 3},
'thickness': 0.8,
'value': value}}
))
fig.update_layout(
template='plotly_dark',
width=width,
height=height,
margin=margin,
)
return fig
def control_graph(self, df):
width = 832
height = 400
margin = dict(l=70, r=100, t=30, b=70)
if df is None or df.empty:
fig = go.Figure()
fig.update_layout(
template='plotly_dark',
xaxis_title='Timestamp',
yaxis_title='Values',
showlegend=True,
width=width,
height=height,
margin=margin,
annotations=[dict(
text="No data",
showarrow=False,
font=dict(size=20, color="white")
)]
)
return fig
fig = go.Figure()
fig.add_trace(
go.Scatter(
x=df['Timestamp'], y=[0.3] * len(df),
mode='lines',
line=dict(dash='dot', color=self.pos_color, width=1),
name='lsl pos'
)
)
fig.add_trace(
go.Scatter(
x=df['Timestamp'], y=[0.5] * len(df),
mode='lines',
line=dict(dash='dot', color=self.pos_color, width=1),
name='usl pos'
)
)
fig.add_trace(
go.Scatter(
x=df['Timestamp'], y=[0.2] * len(df),
mode='lines',
line=dict(dash='dot', color=self.ori_color, width=1),
name='lsl ori'
)
)
fig.add_trace(
go.Scatter(
x=df['Timestamp'], y=[0.6] * len(df),
mode='lines',
line=dict(dash='dot', color=self.ori_color, width=1),
name='usl ori'
)
)
fig.add_trace(
go.Scatter(
x=df['Timestamp'], y=df['Position'],
mode='lines+markers', line=dict(color=self.pos_color),
name='pos'
)
)
fig.add_trace(
go.Scatter(
x=df['Timestamp'], y=df['Orientation'],
mode='lines+markers', line=dict(color=self.ori_color),
name='ori'
)
)
fig.update_layout(
template='plotly_dark',
xaxis_title='Timestamp',
yaxis_title='Valeurs',
showlegend=True,
width=width,
height=height,
margin=margin
)
return fig
def normal_curve(self, df, cote=None):
width = 410
height= 250
margin= dict(l=20, r=70, t=20, b=20)
if df is None or df.empty:
fig = go.Figure()
fig.update_layout(
template='plotly_dark',
showlegend=False,
width=width,
height=height,
margin=margin,
annotations=[dict(
text="No data",
showarrow=False,
font=dict(size=16, color="white")
)]
)
return fig
if cote == 'pos':
color = self.pos_color
lsl = 0.3
usl = 0.5
else:
color = self.ori_color
lsl = 0.2
usl = 0.6
mu_column = f"{cote}_rolling_mean"
std_column = f"{cote}_rolling_std"
idx = df['Timestamp'].idxmax()
mu, std = df.loc[idx, [mu_column, std_column]]
x = np.linspace(mu - 3 * std, mu + 3 * std, 100)
y = norm.pdf(x, mu, std)
fig = go.Figure()
fig.add_trace(
go.Scatter(
x=x, y=y,
mode='lines',
name='Normal Curve',
line=dict(color=color)
)
)
fig.add_shape(
type="line", x0=usl, y0=0, x1=usl, y1=max(y),
line=dict(color="red", width=1, dash="dot"),
name='usl'
)
fig.add_shape(
type="line", x0=lsl, y0=0, x1=lsl, y1=max(y),
line=dict(color="red", width=1, dash="dot"),
name='lsl'
)
fig.update_layout(
template='plotly_dark',
showlegend=False,
width=width,
height=height,
margin=margin
)
return fig
def tool_block(self, df, id=1):
header = f"Tool {id}"
html_content = f"""
<div style="display: flex; align-items: center; justify-content: flex-start; width: 100%;">
<div style="flex: 0 0 2%; border-top: 1px solid white;"></div>
<h2 style="flex: 0 0 auto; margin: 0 10px;">{header}</h2>
<div style="flex: 1; border-top: 1px solid white;"></div>
</div>
"""
gr.HTML(html_content)
with gr.Row():
with gr.Column(scale=1):
gr.Markdown("### `Position`")
with gr.Group():
with gr.Row(height=250):
pos_normal_plot = gr.Plot(
self.normal_curve(
df=df, cote='pos'
)
)
with gr.Row(height=150):
pos_cp_gauge = gr.Plot(
self.gauge(
df=df, type='cp', cote='pos'
)
)
pos_cpk_gauge = gr.Plot(
self.gauge(
df=df, type='cpk', cote='pos'
)
)
with gr.Column(scale=1):
gr.Markdown("### `Orientation`")
with gr.Group():
with gr.Row(height=250):
ori_normal_plot = gr.Plot(
self.normal_curve(
df=df, cote='ori'
)
)
with gr.Row(height=150):
ori_cp_gauge = gr.Plot(
self.gauge(
df=df, type='cp', cote='ori'
)
)
ori_cpk_gauge = gr.Plot(
self.gauge(
df=df, type='cpk', cote='ori'
)
)
with gr.Column(scale=2):
gr.Markdown("### `Control card`")
with gr.Row(height=400):
control_plot = gr.Plot(
self.control_graph(
df=df
)
)
self.plots = [
pos_normal_plot, pos_cp_gauge, pos_cpk_gauge,
ori_normal_plot, ori_cp_gauge, ori_cpk_gauge,
control_plot
]
return self.plots
def refresh(self, df):
return [
self.normal_curve(df, cote='pos'),
self.gauge(df, type='cp', cote='pos'),
self.gauge(df, type='cpk', cote='pos'),
self.normal_curve(df, cote='ori'),
self.gauge(df, type='cp', cote='ori'),
self.gauge(df, type='cpk', cote='ori'),
self.control_graph(df),
]