Plotly Dash Heatmap not updating with dropdown selection - drop-down-menu

I am new to plotly dash and i'm trying to make a heatmap that changes with a dropdown selection. The dropdown is to choose a month, but the heatmap doesn't change!
My data frame is called 'New'.
Here's my code:
Month_Default = New['Month'].unique()
Month_def = 2
#create the dash app
app = dash.Dash()
app.layout = html.Div([
html.H1('//Title'),
html.Div([
html.Div([
html.H4('Select Month...'),
dcc.Dropdown(
id='Month_dropdown',
options=[{'label': i, 'value': i} for i in Month_Default],
value = Month_Def
),
],
style={'width': '48%', 'display': 'inline-block'}),
dcc.Graph(id='heatmap',
figure = {
'data': [go.Heatmap(
x=New['Days'].where(New['Month']==2),
y=New['Hour'],
z=New['Usage'],
colorscale='Viridis')],
'layout': go.Layout(
xaxis = dict(title = 'Days'),
yaxis = dict( title = 'Hours'),
)})
]),])
#app.callback(
dash.dependencies.Output(component_id='heatmap',component_property='figure'),
[dash.dependencies.Input(component_id='Month_dropdown',component_property='value')]
)
def update_graph(Month_dropdown):
filtered_df = New[New['Month'] == Month_dropdown]
heat_fig = go.Heatmap(filtered_df,
x='Days', y='Hour', z='Usage',
colorscale='Viridis',
title='PM KWH Usage')
return heat_fig

have created New dataframe in the way you described it in comments
using dash 2.0.0 hence only need to import dash
two key steps missed
did not app.run_server() to start the dash app
no callback to respond to Dropdown
instead of repeating code in dash layout and callback moved figure creation to just the callback
import dash
from jupyter_dash import JupyterDash
import plotly.graph_objects as go
from dash.dependencies import Input, Output, State
import pandas as pd
import numpy as np
New = pd.DataFrame(
{"date": pd.date_range("1-jan-2021", "15-jun-2021", freq="H")}
).assign(
Usage=lambda d: np.random.uniform(0, 1, len(d)),
Month=lambda d: d["date"].dt.month,
Days=lambda d: d["date"].dt.day,
Hour=lambda d: d["date"].dt.hour,
)
Month_Default = New["Month"].unique()
Month_def = 2
# create the dash app
# app = dash.Dash()
app = JupyterDash(__name__)
app.layout = dash.html.Div(
[
dash.html.H1("//Title"),
dash.html.Div(
[
dash.html.Div(
[
dash.html.H4("Select Month..."),
dash.dcc.Dropdown(
id="Month_dropdown",
options=[{"label": i, "value": i} for i in Month_Default],
value=Month_def,
),
],
style={"width": "48%", "display": "inline-block"},
),
dash.dcc.Graph(id="heatmap"),
]
),
]
)
#app.callback(Output("heatmap", "figure"), Input("Month_dropdown", "value"))
def updateGraph(value):
if not value:
value = Month_def
return {
"data": [
go.Heatmap(
x=New["Days"].where(New["Month"] == value),
y=New["Hour"],
z=New["Usage"],
colorscale="Viridis",
)
],
"layout": go.Layout(
xaxis=dict(title="Days"),
yaxis=dict(title="Hours"),
margin={"l": 0, "r": 0, "t": 0, "b": 0},
),
}
app.run_server(mode="inline")

Related

node-graphviz does not generate the expected png file

I am new to node-graphviz, which is a Node.js interface to the GraphViz graphing tool.
I want to draw a directed graph and save it into memory using the code:
var graphviz = require('graphviz');
var debug = true;
function draw (hbGraph) {
/** Create the digraph */
var vGraph = graphviz.digraph('Happens-Before-Graph'),
eventNodes = {};
/** Create nodes for digraph */
for (var i = 0; i < hbGraph.eventNodes.length; i++) {
/** Note, eventNodes is a sparse array */
var event = hbGraph.eventNodes[i];
if (event != undefined) {
var node = vGraph.addNode(event.id, {
'color': common.COLOR.GREY,
'style': common.STYLE,
});
eventNodes[node.id] = node;
}
}
/** Create edges for digraph, just ignore for this question */
if (debug) {
// Create digraph G
var g = graphviz.digraph("G");
// Add node (ID: Hello)
var n1 = g.addNode( "Hello", {"color" : "blue"} );
n1.set( "style", "filled" );
// Add node (ID: World)
g.addNode( "World" );
// Add edge between the two nodes
var e = g.addEdge( n1, "World" );
e.set( "color", "red" );
// Print the dot script
console.log( g.to_dot() );
// Set GraphViz path (if not in your path)
g.setGraphVizPath( "/usr/local/bin" );
// Generate a PNG output
g.output( "png", "test01.png" );
}
console.log( vGraph.to_dot() );
vGraph.setGraphVizPath( "/usr/local/bin" );
vGraph.output('png', 'test02.png');
}
After running the code, file test01.png is generated while file test02.png is not without any exception. Both two results of to_dot() methods are successfully printed on the console.
The printout of to_dot() method for test02.png is:
digraph Happens-Before-Graph {
"1" [ color = "grey" ];
"7" [ color = "grey" ];
"8" [ color = "grey" ];
"9" [ color = "grey" ];
"10" [ color = "grey" ];
"11" [ color = "grey" ];
"12" [ color = "grey" ];
"13" [ color = "grey" ];
"14" [ color = "grey" ];
}
I want to why file test02.png is not generated and how it can be generated. Could anyone help me?
In addition, the documenation about this library cannot be generated, so I am unfamiliar with it.
Additional information: link to node-graphviz is node-graphviz
The answer is just to remove the minus sign - in the digraph.
Since the documentation of node-graphviz cannot be built, I just post the right answer here.

dc.js charting nested data arrays

Problem description
I have a large data array with a structure similar to the following and seek to create a chart that will display the timerecords' changesets by hour that the changeset was created.
[ // array of records
{
id: 1,
name: 'some record',
in_datetime: '2019-10-24T08:15:00.000000',
out_datetime: '2019-10-24T10:15:00.000000',
hours: 2,
tasks: ["some task name", "another task"],
changesets: [ //array of changesets within a record
{
id: 1001,
created_at: '2019-10-24T09:37:00.000000'
},
...
]
},
...
]
No matter how I have tried to create the dimension/write reduction functions I can't get the correct values out of the data table.
const changeReduceAdd = (p, v) => {
v.changesets.forEach(change => {
let cHour = timeBand[change.created_hour]
if (showByChanges) {
p[cHour] = (p[cHour] || 0) + (change.num_changes || 0)
} else {
p[cHour] = (p[cHour] || 0) + 1 //this is 1 changeset
}
})
return p
}
const changeReduceRemove = (p, v) => {
v.changesets.forEach(change => {
let cHour = timeBand[change.created_hour]
if (showByChanges) {
p[cHour] = (p[cHour] || 0) - (change.num_changes || 0)
} else {
p[cHour] = (p[cHour] || 0) - 1 //this is 1 changeset
}
})
return p
}
const changeReduceInit = () => {
return {}
}
//next create the array dimension of changesets by hour
//goal: show changesets or num_changes grouped by their created_hour
let changeDim = ndx.dimension(r => r.changesets.map(c => timeBand[c.created_hour]), true)
let changeGroup = changeDim.group().reduce(changeReduceAdd, changeReduceRemove, changeReduceInit)
let changeChart = dc.barChart('#changeset-hour-chart')
.dimension(changeDim)
.keyAccessor(d => d.key)
.valueAccessor(d => d.value[d.key])
.group(changeGroup)
jsfiddle and debugging notes
The main problem I'm having is I want the changesets/created_hour chart, but in every dimension I have tried, where the keys appear correct, the values are significantly higher than the expected.
The values in the "8AM" category give value 5, when there are really only 3 changesets which I marked created_hour: 8:
There are a lot of solutions to the "tag dimension" problem, and you happen to have chosen two of the best.
Either
the custom reduction, or
the array/tag flag parameter to the dimension constructor
would do the trick.
Combining the two techniques is what got you into trouble. I didn't try to figure what exactly was going on, but you were somehow summing the counts of the hours.
Simple solution: use the built-in tag dimension feature
Use the tag/dimension flag and default reduceCount:
let changeDim = ndx.dimension(r => r.changesets.map(c => timeBand[c.created_hour]), true)
let changeGroup = changeDim.group(); // no reduce, defaults to reduceCount
let changeChart = dc.barChart('#changeset-hour-chart')
.dimension(changeDim)
.keyAccessor(d => d.key)
.valueAccessor(d => d.value) // no [d.key], value is count
.group(changeGroup)
fork of your fiddle
Manual, pre-1.4 groupAll version
You also have a groupAll solution in your code. This solution was necessary before array/tag dimensions were introduced in crossfilter 1.4.
Out of curiosity, I tried enabling it, and it also works once you transform from the groupAll result into group results:
function groupall_map_to_group(groupall) {
return {
all: () => Object.entries(groupall.value())
.map(([key,value])=>({key,value}))
}
}
let changeGroup = ndx.groupAll().reduce(changeReduceAdd, changeReduceRemove, changeReduceInit)
let changeChart = dc.barChart('#changeset-hour-chart')
.dimension({}) // filtering not implemented
.keyAccessor(d => d.key)
.valueAccessor(d => d.value) // [d.key]
.group(groupall_map_to_group(changeGroup))
.x(dc.d3.scaleBand().domain(timeBand))
.xUnits(dc.units.ordinal)
.elasticY(true)
.render()
crossfilter 1.3 version

Altair Y-Axis Label Left-Alignment & Spacing Edits Possible?

I'm trying to recreate this chart in Altair but can't figure out how to make a few minor edits: https://datawrapper.dwcdn.net/E0jaK/1/
Here's my current progress: https://imgur.com/RMuTU7h
The three edits I'm trying to figure out are:
How to left-align y-axis labels
How to add spacing between the labels and the y-axis
How to move bar number labels to the base of the bars instead of the ends
Any insight on how to implement these edits would be great.
Here's the raw data:
Crime,Count
Larceny/Theft,739
Assault,177
Burglary/Breaking & Entering,133
Destruction of Property/Vandalism,128
Drugs,107
Motor Vehicle Theft,95
Fraud,71
Sex Offenses,57
Suspicious Activity,45
Trespassing,23
Family Offenses,22
Weapons Violations,21
This is the theme I used:
def chart_theme():
font = "Calibri"
return {
"width": 700,
"height": 300,
"background": "white",
"config": {
"title": {
"fontSize": 20,
"anchor": "start"
},
"axisY": {
"labelFont": font,
"labelFontSize": 13,
"labelLimit":200,
"ticks": False,
"titleFont": font,
"titleFontSize": 12,
"titleAlign":"right",
"titleAngle": 0,
"titleY": -10,
"titleX": 25,
},
"view":{"stroke": "transparent",
},
}
}
And here's the chart code:
base = alt.Chart(df, title='San Francisco Crime (11/05 - 11/11)').encode(
x=alt.X('Count', axis=None),
y=alt.Y('Crime', title='Crimes reported to SFPD, by top complaint',
sort=list(df.Crime.values)))
bars = base.mark_bar(size=22).encode(color=alt.condition(
alt.datum.Count > 700,
alt.value('#e17700'),
alt.value('#00648e')))
text = base.mark_text(
color='white',
align='right',
size=12,
dx=-3
).encode(
text='Count')
chart = bars + text
chart
Any guidance/suggestions would be greatly appreciated.
How about something like this
import pandas as pd
import altair as alt
data = {'Larceny/Theft':739,
'Assault':177,
'Burglary/Breaking & Entering':133,
'Destruction of Property/Vandalism':128,
'Drugs':107,
'Motor Vehicle Theft':95,
'Fraud':71,
'Sex Offenses':57,
'Suspicious Activity':45,
'Trespassing':23,
'Family Offenses':22,
'Weapons Violations':21}
df = pd.DataFrame(list(data.items()), columns=['Crime', 'Count'])
base = alt.Chart(df, title='San Francisco Crime (11/05 - 11/11)').encode(
x=alt.X('Count', axis=None),
y=alt.Y('Crime', title='Crimes reported to SFPD, by top complaint',
sort=list(df.Crime.values)))
bars = base.mark_bar(size=22).encode(color=alt.condition(
alt.datum.Count > 700,
alt.value('#e17700'),
alt.value('#00648e')))
text = alt.Chart(df).mark_text(
color='white',
align='left',
x=3
).encode(alt.Text('Count:N'), alt.Y('Crime', sort=list(df.Crime.values)))
chart = bars + text
chart.properties(width=700).configure_axisY(
titleAngle=0,
titleY=-10,
titleX=-60,
labelPadding=160,
labelAlign='left'
)

AnimationHandler has changed for threejs, how can I get it working?

I created a webgl animation using the threejs library, some time ago, today I have been trying to get it to run on the latest version of the three.js library.
In the latest library, there is no pathcontrols.js.
I copied pathcontrols.js from my old library to the new version, but this has not solved the problem,
Below is the full function that does not work properly, but it is the .add() and the animation() calls where I think the problem is:
function initAnimationPath( parent, spline, name, duration ) {
var animationData = {
name: name,
fps: 0.6,
length: duration,
hierarchy: []
};
var i,
parentAnimation, childAnimation,
path = spline.getControlPointsArray(),
sl = spline.getLength(),
pl = path.length,
t = 0,
first = 0,
last = pl - 1;
parentAnimation = { parent: -1, keys: [] };
parentAnimation.keys[ first ] = { time: 0, pos: path[ first ], rot: [ 0, 0, 0, 1 ], scl: [ 1, 1, 1 ] };
parentAnimation.keys[ last ] = { time: duration, pos: path[ last ], rot: [ 0, 0, 0, 1 ], scl: [ 1, 1, 1 ] };
for ( i = 1; i < pl - 1; i++ ) {
t = duration * sl.chunks[ i ] / sl.total;
parentAnimation.keys[ i ] = { time: t, pos: path[ i ] };
}
animationData.hierarchy[ 0 ] = parentAnimation;
THREE.AnimationHandler.add( animationData );
return new THREE.Animation( parent, name, THREE.AnimationHandler.CATMULLROM_FORWARD, false );
};
it seems that the deprecation of animationhandler.add() seems to be the issue, but I am having difficulty working out how to replace it.
(amongst many other things) I tried replacing animationhandler line and animation line with this:
THREE.AnimationHandler.update(delta);
return new THREE.Animation( camera, animationData);
No joy. I would like to know how to get the animation started??
Thanks

Dhtmlxwindow attachURL issue

I have created a dhtmlxwindow object and loaded a jsp page using attachURL.
dhxwindow.attachURL('myPage.jsp');
and in myPage.jsp ,
i have created a layout object.
var mylayout = new dhtmlxLayoutObject(document.body, '3u');
toolbar = mylayout.cells('a').attachToolbar();
toolbar.addButton("Validate", 0, "", "images/queryValidation24.png", "images/queryValidation24.png");
toolbar.addButton("Preview", 1, "", "images/previewBtn24.png", "images/previewBtn24.png");
toolbar.setAlign('right');
//and i have other dhtmlxcomponents in other cells
Problem is i am unable to view the toolbar.
What will be the problem?
First of all you need to use correct syntax as CAPITAL letters:
var mylayout = new dhtmlXLayoutObject(document.body, '3U');
Main page:
dhxWins = new dhtmlXWindows();
dhxWins.enableAutoViewport(false);
dhxWins.attachViewportTo(document.body);
dhxWins.setImagePath("../dhtmlxWindows/codebase/imgs/");
w1 = dhxWins.createWindow("w1", 100, 100, 500, 500);
w1.attachURL("layout_toolbar_test.html");
Attached page:
var mylayout = new dhtmlXLayoutObject(document.body, '3U');
toolbar = mylayout.cells('a').attachToolbar();
toolbar.addButton("Validate", 0, "", "images/queryValidation24.png", "images/queryValidation24.png");
toolbar.addButton("Preview", 1, "", "images/previewBtn24.png", "images/previewBtn24.png");
toolbar.setAlign('right');
Result (sorry, haven't your image files):

Resources