Why is plotly not working, it was working fine with one callback but when i added second callback everything crashed - callback

Code was working with one callback function, but when i added a second callback(change title color feature) everything stopped working and i was given a blank canvas. I would like to be able to see the bar chart, with live adjutable size graph(first callback) and manually adjusting title color(second title) PLEASE HELP, THANK YOU IN ADVANCE! :>
from dash import Dash, dcc, html, Input, Output
import plotly.express as px
from jupyter_dash import JupyterDash
import dash_daq as daq
app = JupyterDash(__name__)
colors = {
'background': '#111111',
'text': '#7FDBFF'
}
picker_style = {'float': 'left', 'margin': 'auto'}
app.layout = html.Div([
html.H1(
children='Hello Dash',
style={
'textAlign': 'center',
'color': colors['text']
}
),
html.P('Live adjustable graph-size(using Dash python)', style={'textAlign': 'center','color': colors['text']}),
html.P('Please manually Change figure width of your choice(+-200px):', style={'textAlign': 'center','color': colors['text']}),
# html.P("Change figure width:", style={'color': colors['text']}),
# dcc.Slider(id='slider', min=500, max=1900, step=200, value=1700,
# marks={x: str(x) for x in [500, 700,900,1100,1300,1500,1700, 1900]},updatemode='drag',tooltip={"placement": "bottom", "always_visible": True}),
dcc.Slider(id='slider', min=500, max=1200, step=100, value=1100,
marks={x: str(x) for x in [500,600,700,800,900,1000,1100,1200]},updatemode='drag',tooltip={"placement": "bottom", "always_visible": True}),
dcc.Graph(id="graph"),
daq.ColorPicker(
id='font', label='Font Color', size=150,
style=picker_style, value=dict(hex='#119DFF')),
daq.ColorPicker(
id='title', label='Title Color', size=150,
style=picker_style, value=dict(hex='#F71016')),
])
#app.callback(
Output("graph", "figure"),
Input('slider', 'value'))
# def display_value(width):
# return 'Width Value: {}'.format(width)
def resize_figure(width):
fig = go.Figure(data=[
go.Bar(name='Monthly Concession Passes',
x=concession["cardholders"],
y=concession["train_price"],
text = concession["train_price"]),
go.Bar(name='Average Fees using Card',
x=concession["cardholders"],
y = concession["MRT Fees"],
text = round(concession["Average Card Fees"],1)),
go.Bar(name='Single Trip Fees(cash)',
x=concession["cardholders"],
y=concession["Single Trip Fees(cash)"],
text = round(concession["Single Trip Fees(cash)"],1))
])
fig.update_layout(
barmode='group',
template="plotly_dark",
paper_bgcolor=colors['background'],
font_color=colors['text'],
title_text=
'Average Monthly Expenditure comparing Concession Passes, Card and Cash for buses',
title_x=0.5,
yaxis={
'title': 'Fees ($)',
# 'rangemode': 'tozero',
'ticks': 'outside'
})
fig.update_layout(width=int(width))
return fig
# #app.callback(
# Output("graph", 'figure'),
# Input("font", 'value'),
# Input("title", 'value')
# )
# def update_bar_chart(font_color, title_color):
# fig = go.Figure(data=[
# go.Bar(name='Monthly Concession Passes',
# x=concession["cardholders"],
# y=concession["train_price"],
# text = concession["train_price"]),
# go.Bar(name='Average Fees using Card',
# x=concession["cardholders"],
# y = concession["MRT Fees"],
# text = round(concession["Average Card Fees"],1)),
# go.Bar(name='Single Trip Fees(cash)',
# x=concession["cardholders"],
# y=concession["Single Trip Fees(cash)"],
# text = round(concession["Single Trip Fees(cash)"],1))
# ])
# fig.update_layout(
# font_color=font_color['hex'],
# title_font_color=title_color['hex'])
# return fig
#app.run_server(mode="inline")
this is data in dictionary:
{'cardholders': {0: 'Primary Student',
1: 'Secondary Student',
2: 'Polytechnic Student',
3: 'University Student',
4: 'Full-time National Serviceman',
5: 'Senior Citizen',
6: 'Adult (Monthly Travel Pass)'},
'bus_price': {0: 24.0, 1: 29.0, 2: 29.0, 3: 55.5, 4: 55.5, 5: 64.0, 6: 128.0},
'train_price': {0: 21.0,
1: 26.5,
2: 26.5,
3: 48.0,
4: 48.0,
5: 64.0,
6: 128.0},
'hybrid_price': {0: 43.5,
1: 54.0,
2: 54.0,
3: 90.5,
4: 90.5,
5: 64.0,
6: 128.0},
'Average Card Fees': {0: 8.149223099487395,
1: 8.149223099487395,
2: 8.149223099487395,
3: 8.149223099487395,
4: 20.208239081660064,
5: 11.538449007368001,
6: 20.208239081660064},
'Average Cash Fees': {0: 17.756768358801253,
1: 17.756768358801253,
2: 17.756768358801253,
3: 17.756768358801253,
4: 30.431152919426268,
5: 22.514797400960248,
6: 30.431152919426268},
'Single Trip Fees(cash)': {0: 69.0,
1: 69.0,
2: 69.0,
3: 69.0,
4: 69.0,
5: 69.0,
6: 69.0},
'MRT Fees': {0: 12.0, 1: 12.0, 2: 12.0, 3: 12.0, 4: 40.5, 5: 20.7, 6: 40.5}}

The main issue is that you cannot have duplicate callback outputs – this isn't supported in Dash (probably because it could lead to a race condition if you have multiple callbacks trying to modify the same figure and they execute at the same time). I understand why you want to break up your callbacks, but in this case, we can actually condense down your code quite a bit anyway, and make your callback more focused.
First, I would define the figure outside of the callback and use dcc.Graph(id="graph", figure=fig) so that the figure is present when the app starts running – this way we don't need to redefine the figure in the callback every time it's executed – we'll design the callback so it only modifies only the width, font color, and title color of the figure's layout.
Then we can combine your two callbacks into one by collecting all of the inputs from both of your original callbacks, and also pass the figure as an input.
Note that when a figure is passed to the callback as an input, it will be in the form of a dictionary, so we'll want to convert the fig argument from the callback to a go.Figure object using something like plotly_fig = go.Figure(fig_dict). Then you can modify the layout of plotly_fig based on the other inputs using plotly_fig.update_layout(...).
Here is a working example:
import pandas as pd
import plotly.graph_objects as go
import plotly.express as px
from dash import Dash, dcc, html, Input, Output
from jupyter_dash import JupyterDash
import dash_daq as daq
concession = pd.DataFrame({'cardholders': {0: 'Primary Student',
1: 'Secondary Student',
2: 'Polytechnic Student',
3: 'University Student',
4: 'Full-time National Serviceman',
5: 'Senior Citizen',
6: 'Adult (Monthly Travel Pass)'},
'bus_price': {0: 24.0, 1: 29.0, 2: 29.0, 3: 55.5, 4: 55.5, 5: 64.0, 6: 128.0},
'train_price': {0: 21.0,
1: 26.5,
2: 26.5,
3: 48.0,
4: 48.0,
5: 64.0,
6: 128.0},
'hybrid_price': {0: 43.5,
1: 54.0,
2: 54.0,
3: 90.5,
4: 90.5,
5: 64.0,
6: 128.0},
'Average Card Fees': {0: 8.149223099487395,
1: 8.149223099487395,
2: 8.149223099487395,
3: 8.149223099487395,
4: 20.208239081660064,
5: 11.538449007368001,
6: 20.208239081660064},
'Average Cash Fees': {0: 17.756768358801253,
1: 17.756768358801253,
2: 17.756768358801253,
3: 17.756768358801253,
4: 30.431152919426268,
5: 22.514797400960248,
6: 30.431152919426268},
'Single Trip Fees(cash)': {0: 69.0,
1: 69.0,
2: 69.0,
3: 69.0,
4: 69.0,
5: 69.0,
6: 69.0},
'MRT Fees': {0: 12.0, 1: 12.0, 2: 12.0, 3: 12.0, 4: 40.5, 5: 20.7, 6: 40.5}})
app = JupyterDash(__name__)
colors = {
'background': '#111111',
'text': '#7FDBFF'
}
picker_style = {'float': 'left', 'margin': 'auto'}
## define the figure
fig = go.Figure(data=[
go.Bar(name='Monthly Concession Passes',
x=concession["cardholders"],
y=concession["train_price"],
text = concession["train_price"]),
go.Bar(name='Average Fees using Card',
x=concession["cardholders"],
y = concession["MRT Fees"],
text = round(concession["Average Card Fees"],1)),
go.Bar(name='Single Trip Fees(cash)',
x=concession["cardholders"],
y=concession["Single Trip Fees(cash)"],
text = round(concession["Single Trip Fees(cash)"],1))
])
fig.update_layout(
barmode='group',
template="plotly_dark",
paper_bgcolor=colors['background'],
font={
'color': colors['text']
},
title_text=
'Average Monthly Expenditure comparing Concession Passes, Card and Cash for buses',
width=1100,
title_x=0.5,
title={
'text': 'Fees ($)',
'font': {'color': '#F71016'}
},
yaxis={
# 'title': 'Fees ($)',
# 'rangemode': 'tozero',
'ticks': 'outside'
})
app.layout = html.Div([
html.H1(
children='Hello Dash',
style={
'textAlign': 'center',
'color': colors['text']
}
),
html.P('Live adjustable graph-size(using Dash python)', style={'textAlign': 'center','color': colors['text']}),
html.P('Please manually Change figure width of your choice(+-200px):', style={'textAlign': 'center','color': colors['text']}),
# html.P("Change figure width:", style={'color': colors['text']}),
# dcc.Slider(id='slider', min=500, max=1900, step=200, value=1700,
# marks={x: str(x) for x in [500, 700,900,1100,1300,1500,1700, 1900]},updatemode='drag',tooltip={"placement": "bottom", "always_visible": True}),
dcc.Slider(id='slider', min=500, max=1200, step=100, value=1100,
marks={x: str(x) for x in [500,600,700,800,900,1000,1100,1200]},updatemode='drag',tooltip={"placement": "bottom", "always_visible": True}),
dcc.Graph(id="graph", figure=fig),
daq.ColorPicker(
id='font', label='Font Color', size=150,
style=picker_style, value=dict(hex='#119DFF')),
daq.ColorPicker(
id='title', label='Title Color', size=150,
style=picker_style, value=dict(hex='#F71016')),
])
#app.callback(
Output("graph", "figure"),
[Input("graph", "figure"),
Input('slider', 'value'),
Input("font", 'value'),
Input("title", 'value')],
prevent_initial_call=True
)
def update_figure(fig_dict, width, font_color, title_color):
plotly_fig = go.Figure(fig_dict)
plotly_fig.update_layout(
width=int(width),
font_color=font_color['hex'],
title_font_color=title_color['hex']
)
return plotly_fig
## I ran this externally, but you can run this inline
app.run_server(mode="external", port=8050)

Related

"ValueError: max_evals=500 is too low for the Permutation explainer" shap answers me do I have to give more data (photos)?

I want to test the explainability of a multiclass semantic segmentation model, deeplab_v3plus with shap to know which features contribute the most to semantic classification. However I have a ValueError: max_evals=500 is too low when running my file, and I struggle to understand the reason.
import glob
from PIL import Image
import torch
from torchvision import transforms
from torchvision.utils import make_grid
import torchvision.transforms.functional as tf
from deeplab import deeplab_v3plus
import shap
def test(args):
# make a video prez
model = deeplab_v3plus('resnet101', num_classes=args.nclass, output_stride=16, pretrained_backbone=True)
model.load_state_dict(torch.load(args.seg_file,map_location=torch.device('cpu'))) # because no gpu available on sandbox environnement
model = model.to(args.device)
model.eval()
explainer = shap.Explainer(model)
with torch.no_grad():
for i, file in enumerate(args.img_folder):
img = img2tensor(file, args)
pred = model(img)
print(explainer(img))
if __name__ == '__main__':
class Arguments:
def __init__(self):
self.device = torch.device("cuda:1" if torch.cuda.is_available() else "cpu")
self.seg_file = "Model_Woodscape.pth"
self.img_folder = glob.glob("test_img/*.png")
self.mean = [0.485, 0.456, 0.406]
self.std = [0.229, 0.224, 0.225]
self.h, self.w = 483, 640
self.nclass = 10
self.cmap = {
1: [128, 64, 128], # "road",
2: [69, 76, 11], # "lanemarks",
3: [0, 255, 0], # "curb",
4: [220, 20, 60], # "person",
5: [255, 0, 0], # "rider",
6: [0, 0, 142], # "vehicles",
7: [119, 11, 32], # "bicycle",
8: [0, 0, 230], # "motorcycle",
9: [220, 220, 0], # "traffic_sign",
0: [0, 0, 0] # "void"
}
args = Arguments()
test(args)
But it returns:
(dee_env) jovyan#jupyter:~/use-cases/Scene_understanding/Code_Woodscape/deeplab_v3+$ python test_shap.py
BILINEAR is deprecated and will be removed in Pillow 10 (2023-07-01). Use Resampling.BILINEAR instead.
Traceback (most recent call last):
File "/home/jovyan/use-cases/Scene_understanding/Code_Woodscape/deeplab_v3+/test_shap.py", line 85, in <module>
test(args)
File "/home/jovyan/use-cases/Scene_understanding/Code_Woodscape/deeplab_v3+/test_shap.py", line 37, in test
print(explainer(img))
File "/home/jovyan/use-cases/Scene_understanding/Code_Woodscape/deeplab_v3+/dee_env/lib/python3.9/site-packages/shap/explainers/_permutation.py", line 82, in __call__
return super().__call__(
File "/home/jovyan/use-cases/Scene_understanding/Code_Woodscape/deeplab_v3+/dee_env/lib/python3.9/site-packages/shap/explainers/_explainer.py", line 266, in __call__
row_result = self.explain_row(
File "/home/jovyan/use-cases/Scene_understanding/Code_Woodscape/deeplab_v3+/dee_env/lib/python3.9/site-packages/shap/explainers/_permutation.py", line 164, in explain_row
raise ValueError(f"max_evals={max_evals} is too low for the Permutation explainer, it must be at least 2 * num_features + 1 = {2 * len(inds) + 1}!")
ValueError: max_evals=500 is too low for the Permutation explainer, it must be at least 2 * num_features + 1 = 1854721!
In the source code it looks like it's because I don't give enough arguments. I only have three images in my test_img/* folder, is that why?
I have the same issue. A possible solution I found which seems to be working for my case is to replace this line
explainer = shap.Explainer(model)
With this line
explainer = shap.explainers.Permutation(model, max_evals = 1854721)
shap.Explainer by default has algorithm='auto'. From the documentation: shape.Explainer
By default the “auto” options attempts to make the best choice given
the passed model and masker, but this choice can always be overriden
by passing the name of a specific algorithm.
Since 'permutation' has been selected you can directly use shap.explainers.Permutation and set max_evals to the value suggested in the error message above.
Given the high number of your use case, this might take a really long time. I would suggest to use an easier model just for testing the above solution.

how to linegraph using result from the previous page

Can i create line graph which is the data get from previous page. I have done a calculation on my previous page. I would like to create line graph using the result and times. I face the problem to adjust the coding below because the coding below show the data was fix.
series: <LineSeries<SalesData, String>>[
LineSeries<SalesData, String>(
dataSource: <SalesData>[
SalesData('Jan', 35),
SalesData('Feb', 28),
SalesData('Mar', 34),
SalesData('Apr', 32),
SalesData('May', 40)
],

mapbox gl fill-extrusion-height restriction decimal values in meter

I was trying to model a detailed building with fill-extrusion feature of mapbox, but I experienced that it takes height in multiplication of 1 meter only.
Please see this JSFiddle:
`http://jsfiddle.net/parveenkaloi/p5w1je7s/20/`
I've set 9 boxes in these sizes (meters):
1: 0.25m,
2: 0.5m,
3: 0.75m,
4: 1.0m,
5: 1.25m,
6: 1.5m,
7: 1.75m,
8: 2.0m,
9: 2.25m
but in result height is :
1: 0.0m,
2: 0.0m,
3: 0.0m,
4: 1.0m,
5: 1.0m,
6: 1.0m,
7: 1.0m,
8: 2.0m,
9: 2.0m
Please help me, if there is any solution for this.
Thanks
You use the old version of the mapbox-gl-js library - v0.38.0. Try latest v0.47.0.
There is also a shorter record for obtaining values - via expressions:
"paint": {
'fill-extrusion-color': ["get", "clr"],
'fill-extrusion-height': ["get", "ht" ],
'fill-extrusion-base': ["get", "pz" ]
}
[ http://jsfiddle.net/n3zvs9jm/1/ ]

Is multiple assignment of tuples slower than multiple assignment statements?

Is there a difference between assigning multiple variables using a tuple, and assigning them in multiple statements?
For example, is there a difference between the following code snippets?
// multiple assignment using tuples
val (x, y) = (str.length, str.substring(1, 2))
// multiple-statement assignment
val x = str.length
val y = str.substring(1, 2)
There is a difference. The approach of using tuples is actually invoking an extractor (the unapply method), which would incur a cost at runtime. The second approach is certainly faster.
To get an idea about the difference, here is a decompilation of two methods showing both approaches. You can see clearly how the first approach causes much more operations.
An important point to note here is that the first expression requires auto-boxing to a java.lang.Integer (because Tuple2 accepts objects), while the second expression uses the value without boxing.
public void m1(java.lang.String);
Code:
0: new #16 // class scala/Tuple2
3: dup
4: aload_1
5: invokevirtual #22 // Method java/lang/String.length:()I
8: invokestatic #28 // Method scala/runtime/BoxesRunTime.boxToInteger:(I)Ljava/lang/Integer;
11: aload_1
12: iconst_1
13: iconst_2
14: invokevirtual #32 // Method java/lang/String.substring:(II)Ljava/lang/String;
17: invokespecial #35 // Method scala/Tuple2."<init>":(Ljava/lang/Object;Ljava/lang/Object;)V
20: astore_3
21: aload_3
22: ifnull 75
25: aload_3
26: invokevirtual #38 // Method scala/Tuple2._1$mcI$sp:()I
29: istore 4
31: aload_3
32: invokevirtual #42 // Method scala/Tuple2._2:()Ljava/lang/Object;
35: checkcast #18 // class java/lang/String
38: astore 5
40: new #16 // class scala/Tuple2
43: dup
44: iload 4
46: invokestatic #28 // Method scala/runtime/BoxesRunTime.boxToInteger:(I)Ljava/lang/Integer;
49: aload 5
51: invokespecial #35 // Method scala/Tuple2."<init>":(Ljava/lang/Object;Ljava/lang/Object;)V
54: astore 6
56: aload 6
58: astore_2
59: aload_2
60: invokevirtual #38 // Method scala/Tuple2._1$mcI$sp:()I
63: istore 7
65: aload_2
66: invokevirtual #42 // Method scala/Tuple2._2:()Ljava/lang/Object;
69: checkcast #18 // class java/lang/String
72: astore 8
74: return
75: new #44 // class scala/MatchError
78: dup
79: aload_3
80: invokespecial #47 // Method scala/MatchError."<init>":(Ljava/lang/Object;)V
83: athrow
public void m2(java.lang.String);
Code:
0: aload_1
1: invokevirtual #22 // Method java/lang/String.length:()I
4: istore_2
5: aload_1
6: iconst_1
7: iconst_2
8: invokevirtual #32 // Method java/lang/String.substring:(II)Ljava/lang/String;
11: astore_3
12: return
}

Unnecessary load and store instruction in scala's byte code

I just did some inverstigation on pattern match and its corresponding byte code.
val a = Array(1,2,3,4)
a.map {
case i => i + 1
}
For above code, I use javap and got the byte code for the annonymous function inside map:
public int apply$mcII$sp(int);
Code:
0: iload_1
1: istore_2
2: iload_2
3: iconst_1
4: iadd
5: ireturn
So it seems to me that in line 0 we push an int (the parameter), then in line 1 we load the int and in line 2 we push it back ... What's the purpose here?
Thanks!
Dude, try -optimise.
public int apply$mcII$sp(int);
flags: ACC_PUBLIC
Code:
stack=2, locals=2, args_size=2
0: iload_1
1: iconst_1
2: iadd
3: ireturn
Use
scala> :javap -prv -
and then something like
scala> :javap -prv $line4/$read$$iw$$iw$$anonfun$1
This is not really an answer, since I couldn't figure out why this happens. I'm hoping that these observations will be at least helpful :)
I'm seeing the following bytecode in Scala 2.10:
public int apply$mcII$sp(int);
Code:
0: iload_1 ; var1 -> stack
1: istore_2 ; var2 <- stack
2: iload_2 ; var2 -> stack
3: iconst_1 ; 1 -> stack
4: iadd
5: istore_3 ; var3 <- stack
6: iload_3 ; var3 -> stack
7: ireturn ; return <- stack
The first two instructions seem to simply move the value of var1 to var2, then move var2 to the stack as a parameter. The same can be observed after iadd, where the result is stored in var3 for no apparent reason, since ireturn returns the value from the stack anyway.