diff --git a/assets/app.css b/assets/app.css index 9b14b1237fb298719d662c2ddb0e40dc9998a2a1..217689caec6a601f1d127f33ac4080319054f69b 100755 --- a/assets/app.css +++ b/assets/app.css @@ -77,4 +77,8 @@ button:focus{ border: 1px solid rgba(68, 71, 99,.24); color: rgb(68, 71, 99); background-color: rgba(68, 71, 99, 0.116); +} + +.Select-control{ + width: 100% !important; } \ No newline at end of file diff --git a/src/Modules/General/callbacks.py b/src/Modules/General/callbacks.py index dbc14658484d51f8d5137779ce964522d2ed6a04..0a654270a6e906cb5f2114b3721c39e44c46ed3e 100644 --- a/src/Modules/General/callbacks.py +++ b/src/Modules/General/callbacks.py @@ -63,6 +63,7 @@ class callbacks(): graphs = {l:[] for l in generalLayerFilter} annotations = [] + for layer in generalLayerFilter: i = 0 for f in generalGraphFilter: @@ -70,7 +71,7 @@ class callbacks(): if(layer not in super.SpikeGraphY): super.SpikeGraphY[layer] = deque(maxlen=100) super.MaxSpike[layer] = 0 - if data != None and layer in data[i]: + if data[i] != None and layer in data[i]: super.SpikeGraphY[layer].append(data[i][layer]["spikes"]) else: super.SpikeGraphY[layer].append(0) @@ -86,7 +87,7 @@ class callbacks(): fill='tozeroy' if len( generalGraphFilter) == 1 else 'none', line=dict(color="rgb(31, 119, 180)"), - name='Spikes', + name='Spikes ['+layer+']', mode='lines+markers', text=list(super.xAxisLabel), customdata=list(super.SpikeGraphY[layer]), @@ -97,7 +98,7 @@ class callbacks(): if(layer not in super.SynapseGraphY): super.SynapseGraphY[layer] = deque(maxlen=100) super.MaxSynapse[layer] = 0 - if data != None and layer in data[i]: + if data[i] != None and layer in data[i]: super.SynapseGraphY[layer].append(data[i][layer]["synapseUpdate"]) else: super.SynapseGraphY[layer].append(0) @@ -111,7 +112,7 @@ class callbacks(): fill='tozeroy' if len( generalGraphFilter) == 1 else 'none', line=dict(color="rgb(255, 127, 14)"), - name='Synapses update', + name='Synapses activity ['+layer+']', mode='lines+markers', text=list(super.xAxisLabel), customdata=list(super.SynapseGraphY[layer]), @@ -120,7 +121,7 @@ class callbacks(): if(layer not in super.PotentialGraphY): super.PotentialGraphY[layer] = deque(maxlen=100) super.MaxPotential[layer] = 0 - if data != None and layer in data[i]: + if data[i] != None and layer in data[i]: super.PotentialGraphY[layer].append(data[i][layer]["potential"]) else: super.PotentialGraphY[layer].append(0) @@ -135,85 +136,74 @@ class callbacks(): fill='tozeroy' if len( generalGraphFilter) == 1 else 'none', line=dict(color="rgb(44, 160, 44)"), - name="Neuron's potential update", + name='Neuron\'s potential ['+layer+']', mode='lines+markers', text=list(super.xAxisLabel), customdata=list(super.PotentialGraphY[layer]), hovertemplate="%{text} <br> <b>%{customdata}</b> <br> <b>Max</b> "+str(super.MaxPotential[layer]))) i += 1 - if(g.Labels != None): + if(len(graphs) != 0): - if(data[-1] != None): - super.LossGraphY.append(round(data[-1], 2)) - else: - super.LossGraphY.append(None) + if(g.Labels != None): - fig = make_subplots(rows=1+(len(graphs)*1), cols=1, shared_xaxes=True, vertical_spacing=0.05, specs= - [[{'rowspan': 1}]] +[[{'rowspan': 1}] for l in graphs]) + if(data[-1] != None): + super.LossGraphY.append(round(data[-1], 2)) + else: + super.LossGraphY.append(None) + + fig = make_subplots(rows=1+(len(graphs)*1), cols=1, shared_xaxes=True, vertical_spacing=0.05, specs= + [[{'rowspan': 1}]] +[[{'rowspan': 1}] for l in graphs]) - fig.add_trace( - go.Scatter(x=list(super.InfoGraphX), y=list(super.LossGraphY), mode='lines', - text=[ - str(t)+' %' for t in list(super.LossGraphY)], - hoverinfo='text', - connectgaps=False, - xaxis='x2', - line={"color": "#dc3545", - "dash": "dot", - "width": 2}, - name='Loss' - ), - row=1, col=1 - ) - - for key,graph in graphs.items: fig.add_trace( - graph, row=3, col=1) + go.Scatter(x=list(super.InfoGraphX), y=list(super.LossGraphY), mode='lines', + text=[ + str(t)+' %' for t in list(super.LossGraphY)], + hoverinfo='text', + connectgaps=False, + xaxis='x2', + line={"color": "#dc3545", + "dash": "dot", + "width": 2}, + name='Loss' + ), + row=1, col=1 + ) + + for key,graph in graphs.items: + fig.add_trace( + graph, row=3, col=1) - fig['layout'].update( - xaxis2=dict( - title='Step', - autorange=True, - range=[min(super.InfoGraphX) if super.InfoGraphX else 0, max( - super.InfoGraphX) if super.InfoGraphX else 0], - #rangeslider={'visible': True,'autorange': True}, - # showticklabels=False, - tickvals=list(super.InfoGraphX), - ), - yaxis1=dict( - range=[0, 105] - ), - showlegend=True, - uirevision='no reset of zoom', - margin={'l': 0, 'r': 0, 't': 30, 'b': 25}, - annotations=annotations) - else: - fig = make_subplots( - rows=len(graphs), cols=1, shared_xaxes=True, vertical_spacing=0.05) + else: + fig = make_subplots( + rows=len(graphs), cols=1, shared_xaxes=True,vertical_spacing=0.05) - l = 1 - for key,graphL in graphs.items(): - for graph in graphL: - fig.add_trace( - graph, row=l, col=1) - l +=1 + l = 1 + for key,graphL in graphs.items(): + for graph in graphL: + fig.add_trace( + graph, row=l, col=1) + l +=1 + + fig.update_xaxes(title_text="Step", row=len(graphs), col=1) fig['layout'].update( - # TODO: change axis when there is no Loss - xaxis=dict( - title='Step', - autorange=True, - range=[min(super.InfoGraphX) if super.InfoGraphX else 0, max( - super.InfoGraphX) if super.InfoGraphX else 0], - #rangeslider={'visible': True,'autorange': True}, - # showticklabels=False, - tickvals=list(super.InfoGraphX)), - yaxis=dict(range=[0, 105]), - showlegend=True, - uirevision='no reset of zoom', - margin={'l': 0, 'r': 0, 't': 30, 'b': 25}, - annotations=annotations) + yaxis=dict(range=[0, 105]), + showlegend=True, + uirevision='no reset of zoom', + margin={'l': 0, 'r': 0, 't': 30, 'b': 25}, + annotations=annotations) + + else: + + fig = make_subplots(rows=1, cols=1, shared_xaxes=True, vertical_spacing=0.05, specs=[[{'rowspan': 1}]]) + fig.add_trace( + go.Scatter(x=list(), y=list(), mode='lines', + line={"color": "#dc3545", + "dash": "dot", + "width": 2}, + ),row=1, col=1) + return fig except Exception as e: diff --git a/src/Modules/General/layout.py b/src/Modules/General/layout.py index c18e30197ea55761092b11e0df9d41d788709277..abb951fc384b34ad84277e15287e34046e1dcb22 100644 --- a/src/Modules/General/layout.py +++ b/src/Modules/General/layout.py @@ -68,6 +68,7 @@ class layout(): self.SpikeGraphY.clear() self.LossGraphY.clear() self.SynapseGraphY.clear() + self.PotentialGraphY.clear() self.xAxisLabel.clear() self.Label.clear() self.MaxPotential = dict() @@ -133,18 +134,18 @@ class layout(): # Graphs filter dcc.Dropdown( id='GeneralGraphFilter', - options=[{'label': "Spikes", 'value': "Spikes"}, {'label': "Synapses update", 'value': "Synapses"}, { - 'label': "Neurons potential update", 'value': "Potentials"}], + options=[{'label': "Spikes", 'value': "Spikes"}, {'label': "Synapses activity", 'value': "Synapses"}, { + 'label': "Neurons potential", 'value': "Potentials"}], value=['Spikes'], multi=True, - style={'width': '50%', "marginLeft": "10px", "textAlign": "start"}), + style={"minWidth":"10%","marginLeft": "10px", "textAlign": "start"}), # Layers filter dcc.Dropdown( id='GeneralLayerFilter', options=[{'label': str(i), 'value': str(i)} for i in (i for i in g.Layer_Neuron if i != "Input")], value=[str(i) for i in (i for i in g.Layer_Neuron if i != "Input")], multi=True, - style={'width': '50%', "marginLeft": "5px", "textAlign": "start"})], className="row", style={"paddingLeft": "20px"}) + style={"minWidth":"10%","marginLeft": "15px", "textAlign": "start"})], className="row", style={"paddingLeft": "20px",'width': '100%'}) ], className="col-12") ], className="row"), html.Div([dcc.Graph(id='general-graph', animate=False, config={"displaylogo": False})])], className="col-lg-9 col-sm-12 col-xs-12" if(g.Labels != None) else "col-lg-12 col-sm-12 col-xs-12"),