Using dash_cytoscape line-gradient-stop-colors - python

I am attempting to create gradients within the edges of a graph in dash_cytoscape using line-gradient-stop-colors (from the js.cytoscape documentation). I am doing this with a stylesheet that describes a gradient layout for all of the edges in my graph. Example code is below, however it creates a graph with just grey edges.
import dash
import dash_cytoscape as cyto
from dash import html
app = dash.Dash(__name__)
style_1 = [
{
'selector': 'node',
'style': {
'label': 'data(id)',
'background-color': 'blue',
}
},
{
'selector': 'edge',
'style': {
'line-gradient-stop-colors': 'cyan magenta yellow', # these are the lines that I have issue with
'line-gradient-stop-positions': '25 50 75',
}
}
]
app.layout = html.Div([
cyto.Cytoscape(
id='cytoscape-elements-boolean',
layout={'name': 'preset'},
style={'width': '100%', 'height': '800px'},
stylesheet=style_1,
elements=[
{
'data': {'id': 'one'},
'position': {'x': 75, 'y': 75},
},
{
'data': {'id': 'two'},
'position': {'x': 75, 'y': 200},
},
{
'data': {'id': 'three'},
'position': {'x': 200, 'y': 75},
},
{
'data': {'id': 'four'},
'position': {'x': 200, 'y': 200}
},
{'data': {'source': 'one', 'target': 'two'}},
{'data': {'source': 'two', 'target': 'three'}},
{'data': {'source': 'three', 'target': 'four'}},
{'data': {'source': 'two', 'target': 'four'}},
]
)
])
if __name__ == '__main__':
app.run_server(debug=True)
I believe the issue is how I have the line-gradient-stop-colors string set up but I've tried multiple options and none of them have worked. Any help would be greatly appreciated!

Related

python dash cyto layouts - how to use "depthfirstsearch"

I got breadthfirst working like:
app = dash.Dash()
cyto.load_extra_layouts()
app.layout = html.Div([
html.P("Dash Cytoscape:"),
cyto.Cytoscape(
id='cytoscape',
elements=[
{'data': {'id': 'ca', 'label': 'Canada'}},
{'data': {'id': 'on', 'label': 'Ontario'}},
{'data': {'id': 'qc', 'label': 'Quebec'}},
{'data': {'source': 'ca', 'target': 'on'}},
{'data': {'source': 'ca', 'target': 'qc'}}
],
layout={
'name': 'breadthfirst',
"fit": False,
},
style={'width': '100%', 'height': '700px'},
)
])
app.run_server(debug=True, use_reloader=False) # Turn off reloader if inside Jupyter
but how do I get this other method hacked in?
https://js.cytoscape.org/#eles.depthFirstSearch

Correct callback for networkx dash connectivity

I am trying to create a simple networkx and dash dashboard with a dropdown to select either successors, predecessors, or connected then when I click on a node it will return that info.
For example, if I select predecessors and then click on Texas, it will provide US, but if I select successors and click on it, it will show Houston.
If I select connected and click on Texas, it will respond with US and Houston.
Would anyone know the correct callback function that I would need to create to accomplish this?
import dash
import dash_core_components as dcc
import dash_html_components as html
import dash_cytoscape as cyto
from dash.dependencies import Input, Output
import plotly.express as px
app = dash.Dash(__name__)
app.layout = html.Div([
html.P("Dash Cytoscape:"),
cyto.Cytoscape(
id='cytoscape',
elements=[
{'data': {'id': 'ca', 'label': 'Canada'}},
{'data': {'id': 'on', 'label': 'Ontario'}},
{'data': {'id': 'qc', 'label': 'Quebec'}},
{'data': {'id': 'us', 'label': 'US'}},
{'data': {'id': 'ny', 'label': 'New York'}},
{'data': {'id': 'tx', 'label': 'Texas'}},
{'data': {'id': 'fl', 'label': 'Florida'}},
{'data': {'id': 'mia', 'label': 'Miami'}},
{'data': {'id': 'hou', 'label': 'Houston'}},
{'data': {'source': 'ca', 'target': 'on'}},
{'data': {'source': 'ca', 'target': 'qc'}},
{'data': {'source': 'us', 'target': 'ny'}},
{'data': {'source': 'us', 'target': 'tx'}},
{'data': {'source': 'us', 'target': 'fl'}},
{'data': {'source': 'tx', 'target': 'hou'}},
{'data': {'source': 'fl', 'target': 'mia'}}
],
layout = {'name':'breadthfirst', 'directed':True},
style={'width': '400px', 'height': '500px'}
)
])
#app.callback(Output('cytoscape-tapNodeData-output', 'children'),
Input('cytoscape-event-callbacks-2', 'tapNodeData'))
def displayTapNodeData(data):
if data:
return
app.run_server(debug=True)
I add the necessary callback to make the dropdown menu working along with the clicking on the nodes. You need only to manipulate how to extract the data from the list edges and nodes in the callback function, and it will be pure python problem, and you can use directly the edges and nodes list inside the callback function without passing them as parameters.
import dash
import dash_cytoscape as cyto
import dash_html_components as html
import dash_core_components as dcc
from dash.dependencies import Input, Output
app = dash.Dash(__name__)
styles = {
'pre': {
'border': 'thin lightgrey solid',
'overflowX': 'scroll'
}
}
nodes = [
{
'data': {'id': short, 'label': label},
}
for short, label in (
('la', 'Los Angeles'),
('nyc', 'New York'),
('to', 'Toronto'),
('mtl', 'Montreal'),
('van', 'Vancouver'),
('chi', 'Chicago'),
('bos', 'Boston'),
('hou', 'Houston')
)
]
edges = [
{'data': {'source': source, 'target': target}}
for source, target in (
('van', 'la'),
('la', 'chi'),
('hou', 'chi'),
('to', 'mtl'),
('mtl', 'bos'),
('nyc', 'bos'),
('to', 'hou'),
('to', 'nyc'),
('la', 'nyc'),
('nyc', 'bos')
)
]
default_stylesheet = [
{
'selector': 'node',
'style': {
'background-color': '#BFD7B5',
'label': 'data(label)'
}
}
]
app.layout = html.Div([
cyto.Cytoscape(
id='cytoscape',
layout={'name':'breadthfirst','directed':True},
elements=edges+nodes,
stylesheet=default_stylesheet,
style={'width': '100%', 'height': '450px'}
),
html.Div([
dcc.Dropdown(['predecessors', 'successors', 'connected'], 'predecessors', id='cyto-dropdown')
]),
html.Div(id='my-output'),
])
#app.callback(Output('my-output', 'children'),
[Input('cyto-dropdown', 'value'),
Input('cytoscape', 'tapNodeData')])
def displayTapNodeData(value, data):
if data:
if value == 'successors':
return "The successor node(s): " + data['id']
elif value == 'predecessors':
return "The predecessor node(s) " + data['id']
elif value == 'connected':
return "The connected node(s): " + data['id']
if __name__ == '__main__':
app.run_server(debug=True, use_reloader=False)

TimestampedGeoJson with MultiPolygon shows Time Not Available

I want to display a shape over the Canada map.
The idea is 2 shapes in different years.
But my slide at the end says:
"Time Not Available"
I tried to find here at the community, but I haven't found a problem like it.
Here you can find my file and here you can find my code:
import folium
from folium.plugins import TimestampedGeoJson
import json
import pandas as pd
with open('outputfile.json') as f:
poly = json.load(f)
features = [
{
'type': 'Feature',
'geometry': {
'type': 'MultiPolygon',
'coordinates': pol['coordinates'],
},
'properties': {
'ABBREVNAME': pol['ABBREVNAME'],
'time': pol['date'],
}
} for pol in poly
]
mapa = folium.Map(
location = [56.130,-106.35],
tiles='openstreetmap',
zoom_start = 3
)
TimestampedGeoJson({'type': 'FeatureCollection', 'features': features}).add_to(mapa)
mapa
Thanks!!!
I had the same problem of yours of time not available and solved by following the example on the documentation and this other post.
Basically, some key points from doc:
1- It's is not 'time' but "times" and it must be the same length of the list of coordinates
2- Lookout for time format it only takes ISO or ms epoch
enter image description here
Here is a code example of a store location code i was working, I didn't try Polygon yet but hope it helps u:
m = folium.Map([-23.579782, -46.687754], zoom_start=6, tiles="cartodbpositron")
TimestampedGeoJson({
'type': 'FeatureCollection',
'features': [
{
'type': 'Feature',
'geometry': {
'type': 'LineString',
'coordinates': [[-46.687754, -23.579782]],
},
'properties': {
'icon': 'marker',
'iconstyle': {
'iconSize': [20, 20],
'iconUrl':
'https://img.icons8.com/ios-filled/50/000000/online-store.png'
},
'id': 'house',
'popup': 1,
'times': [1633046400000.0]
}
}, {
'type': 'Feature',
'geometry': {
'type': 'LineString',
'coordinates': [[-46.887754, -23.579782]],
},
'properties': {
'icon': 'marker',
'iconstyle': {
'iconSize': [20, 20],
'iconUrl':
'https://img.icons8.com/ios-filled/50/000000/online-store.png'
},
'id': 'house',
'popup': 1,
'times': [1635046400000.0]
}
}
]
}).add_to(m)
folium_static(m)
m.save('test.html')

Dash:graph_update with multiple drop down selection condition

Hello I am very new to dash and I am trying to render a graph whose outpuut would depend on the two drop down selection on the layput
I have written the below graph_update logic, however somehow it is not workig.
app.layout = html.Div([
html.Div([
html.H1('Stock Tickers'),
dcc.Dropdown(
id='my-dropdown',
options=[
{'label': 'A', 'value': 'A'},
{'label': 'B', 'value': 'B'},
{'label': 'C', 'value': 'C'}
],
value='A'
)
],
style={'width': '20%', 'display': 'inline-block'}
),
dcc.Dropdown(
id='my-dropdown1',
options=[
{'label': '250,000', 'value': '250000'},
{'label': '500,000', 'value': '500000'},
{'label': '750,000', 'value': '750000'},
{'label': '1,000,000', 'value': '1000000'}
],
value='250000'
),
dcc.Graph(id='my-graph')
], className="container")
#app.callback(Output('my-graph', 'figure'),
[Input('my-dropdown', 'value'), Input('my-dropdown1', 'value')])
def update_graph(selected_dropdown_value, selected_imp_value):
dff = df[(df['Demo'] == selected_dropdown_value) & (df['Imp_cap'] == selected_impresession_value)]
return {
'data': [{
'x': dff.Imp
'y': dff.user,
'line': {
'width': 3,
'shape': 'spline'
}
}],
'layout': {
'margin': {
'l': 30,
'r': 20,
'b': 30,
't': 20
}
}
}
I was hoping if someone can please help me to resolve the issue
Thanks a lot in advance !!
This is how we managed to do it. It was not something exceptionally genius, just the way of writing it.
def update_graph(n_clicks, input1, input2, input3, input4):
dff = df[df['Demo'] == input1]
df1 = dff[dff['Month'] == input2]
df2 = df1[df1['Imp'] == input3]
df3 = df2[df2['imp_cap'] == input4]
if n_clicks < 1:
return []
else:
return {
'data': [{
'x': df3.Variable2,
'y': df3.Variable1,
'line': {
'width': 3,
'shape': 'spline'
}
}],
'layout': dict(
# 'margin': {
# 'l': 30,
# 'r': 20,
# 'b': 30,
# 't': 50
# },
title='title',
xaxis=dict(title='x-title'),
yaxis=dict(title='y-title'),
annotations=[make_annotation_item(x=df3['Variable1'].iloc[-1], y=df3['Variable2'].iloc[-1])]
)
}

Plotly error: Invalid 'figure_or_data' argument

an animation example from this plotly tutorial is not working with Plotly 2.0.12. I put the error output below. Is there any way to solve the problem? I am using plotly on a Jupyter Notebook.
PlotlyError: Invalid 'figure_or_data' argument. Plotly will not be
able to properly parse the resulting JSON. If you want to send this
'figure_or_data' to Plotly anyway (not recommended), you can set
'validate=False' as a plot option.
Here's why you're seeing this error:
'slider' is not allowed in 'layout'
Path To Error: ['layout']['slider']
Valid attributes for 'layout' at path ['layout'] under parents
['figure']:
['angularaxis', 'annotations', 'autosize', 'bargap', 'bargroupgap',
'barmode', 'barnorm', 'boxgap', 'boxgroupgap', 'boxmode', 'calendar',
'direction', 'dragmode', 'font', 'geo', 'height', 'hiddenlabels',
'hiddenlabelssrc', 'hidesources', 'hoverlabel', 'hovermode',
'images',
'legend', 'mapbox', 'margin', 'orientation', 'paper_bgcolor',
'plot_bgcolor', 'radialaxis', 'scene', 'separators', 'shapes',
'showlegend', 'sliders', 'smith', 'ternary', 'title', 'titlefont',
'updatemenus', 'width', 'xaxis', 'yaxis']
Run `<layout-object>.help('attribute')` on any of the above.
'<layout-object>' is the object at ['layout']
EDIT: Just noticed the link is broken. Here is the full code:
from plotly.offline import init_notebook_mode, iplot
from IPython.display import display, HTML
import pandas as pd
init_notebook_mode(connected=True)
url = 'https://raw.githubusercontent.com/plotly/datasets/master/gapminderDataFiveYear.csv'
dataset = pd.read_csv(url)
years = ['1952', '1962', '1967', '1972', '1977', '1982', '1987', '1992', '1997', '2002', '2007']
# make list of continents
continents = []
for continent in dataset['continent']:
if continent not in continents:
continents.append(continent)
# make figure
figure = {
'data': [],
'layout': {},
'frames': [],
'config': {'scrollzoom': True}
}
# fill in most of layout
figure['layout']['xaxis'] = {'range': [30, 85], 'title': 'Life Expectancy'}
figure['layout']['yaxis'] = {'title': 'GDP per Capita', 'type': 'log'}
figure['layout']['hovermode'] = 'closest'
figure['layout']['slider'] = {
'args': [
'slider.value', {
'duration': 400,
'ease': 'cubic-in-out'
}
],
'initialValue': '1952',
'plotlycommand': 'animate',
'values': years,
'visible': True
}
figure['layout']['updatemenus'] = [
{
'buttons': [
{
'args': [None, {'frame': {'duration': 500, 'redraw': False},
'fromcurrent': True, 'transition': {'duration': 300, 'easing': 'quadratic-in-out'}}],
'label': 'Play',
'method': 'animate'
},
{
'args': [[None], {'frame': {'duration': 0, 'redraw': False}, 'mode': 'immediate',
'transition': {'duration': 0}}],
'label': 'Pause',
'method': 'animate'
}
],
'direction': 'left',
'pad': {'r': 10, 't': 87},
'showactive': False,
'type': 'buttons',
'x': 0.1,
'xanchor': 'right',
'y': 0,
'yanchor': 'top'
}
]
sliders_dict = {
'active': 0,
'yanchor': 'top',
'xanchor': 'left',
'currentvalue': {
'font': {'size': 20},
'prefix': 'Year:',
'visible': True,
'xanchor': 'right'
},
'transition': {'duration': 300, 'easing': 'cubic-in-out'},
'pad': {'b': 10, 't': 50},
'len': 0.9,
'x': 0.1,
'y': 0,
'steps': []
}
# make data
year = 1952
for continent in continents:
dataset_by_year = dataset[dataset['year'] == year]
dataset_by_year_and_cont =
dataset_by_year[dataset_by_year['continent'] == continent]
data_dict = {
'x': list(dataset_by_year_and_cont['lifeExp']),
'y': list(dataset_by_year_and_cont['gdpPercap']),
'mode': 'markers',
'text': list(dataset_by_year_and_cont['country']),
'marker': {
'sizemode': 'area',
'sizeref': 200000,
'size': list(dataset_by_year_and_cont['pop'])
},
'name': continent
}
figure['data'].append(data_dict)
# make frames
for year in years:
frame = {'data': [], 'name': str(year)}
for continent in continents:
dataset_by_year = dataset[dataset['year'] == int(year)]
dataset_by_year_and_cont =
dataset_by_year[dataset_by_year['continent'] == continent]
data_dict = {
'x': list(dataset_by_year_and_cont['lifeExp']),
'y': list(dataset_by_year_and_cont['gdpPercap']),
'mode': 'markers',
'text': list(dataset_by_year_and_cont['country']),
'marker': {
'sizemode': 'area',
'sizeref': 200000,
'size': list(dataset_by_year_and_cont['pop'])
},
'name': continent
}
frame['data'].append(data_dict)
figure['frames'].append(frame)
slider_step = {'args': [
[year],
{'frame': {'duration': 300, 'redraw': False},
'mode': 'immediate',
'transition': {'duration': 300}}
],
'label': year,
'method': 'animate'}
sliders_dict['steps'].append(slider_step)
figure['layout']['sliders'] = [sliders_dict]
iplot(figure)
I do not know if I have to downgrade the version (and, in case, to which one) but I'd rather not.
I validated your code and found some errors.
On Line 29 you should have given
figure['layout']['sliders'] instead of figure['layout']['slider']
Plotly offline's iplot function has a separate parameter of inputting config of the plot.
So the below line
# make figure
figure = {
'data': [],
'layout': {},
'frames': [],
'config': {'scrollzoom': True}
}
and the line
iplot(figure)
should actually be written as
# make figure
figure = {
'data': [],
'layout': {},
'frames': []
}
config = {'scrollzoom': True}
and
iplot(figure, config=config)
So the final working code should be
from plotly.offline import init_notebook_mode, iplot
from IPython.display import display, HTML
import pandas as pd
init_notebook_mode(connected=True)
url = 'https://raw.githubusercontent.com/plotly/datasets/master/gapminderDataFiveYear.csv'
dataset = pd.read_csv(url)
years = ['1952', '1962', '1967', '1972', '1977', '1982', '1987', '1992', '1997', '2002', '2007']
# make list of continents
continents = []
for continent in dataset['continent']:
if continent not in continents:
continents.append(continent)
# make figure
figure = {
'data': [],
'layout': {},
'frames': []
}
config = {'scrollzoom': True}
# fill in most of layout
figure['layout']['xaxis'] = {'range': [30, 85], 'title': 'Life Expectancy'}
figure['layout']['yaxis'] = {'title': 'GDP per Capita', 'type': 'log'}
figure['layout']['hovermode'] = 'closest'
figure['layout']['sliders'] = {
'args': [
'slider.value', {
'duration': 400,
'ease': 'cubic-in-out'
}
],
'initialValue': '1952',
'plotlycommand': 'animate',
'values': years,
'visible': True
}
figure['layout']['updatemenus'] = [
{
'buttons': [
{
'args': [None, {'frame': {'duration': 500, 'redraw': False},
'fromcurrent': True, 'transition': {'duration': 300, 'easing': 'quadratic-in-out'}}],
'label': 'Play',
'method': 'animate'
},
{
'args': [[None], {'frame': {'duration': 0, 'redraw': False}, 'mode': 'immediate',
'transition': {'duration': 0}}],
'label': 'Pause',
'method': 'animate'
}
],
'direction': 'left',
'pad': {'r': 10, 't': 87},
'showactive': False,
'type': 'buttons',
'x': 0.1,
'xanchor': 'right',
'y': 0,
'yanchor': 'top'
}
]
sliders_dict = {
'active': 0,
'yanchor': 'top',
'xanchor': 'left',
'currentvalue': {
'font': {'size': 20},
'prefix': 'Year:',
'visible': True,
'xanchor': 'right'
},
'transition': {'duration': 300, 'easing': 'cubic-in-out'},
'pad': {'b': 10, 't': 50},
'len': 0.9,
'x': 0.1,
'y': 0,
'steps': []
}
# make data
year = 1952
for continent in continents:
dataset_by_year = dataset[dataset['year'] == year]
dataset_by_year_and_cont=dataset_by_year[dataset_by_year['continent'] == continent]
data_dict = {
'x': list(dataset_by_year_and_cont['lifeExp']),
'y': list(dataset_by_year_and_cont['gdpPercap']),
'mode': 'markers',
'text': list(dataset_by_year_and_cont['country']),
'marker': {
'sizemode': 'area',
'sizeref': 200000,
'size': list(dataset_by_year_and_cont['pop'])
},
'name': continent
}
figure['data'].append(data_dict)
# make frames
for year in years:
frame = {'data': [], 'name': str(year)}
for continent in continents:
dataset_by_year = dataset[dataset['year'] == int(year)]
dataset_by_year_and_cont=dataset_by_year[dataset_by_year['continent'] == continent]
data_dict = {
'x': list(dataset_by_year_and_cont['lifeExp']),
'y': list(dataset_by_year_and_cont['gdpPercap']),
'mode': 'markers',
'text': list(dataset_by_year_and_cont['country']),
'marker': {
'sizemode': 'area',
'sizeref': 200000,
'size': list(dataset_by_year_and_cont['pop'])
},
'name': continent
}
frame['data'].append(data_dict)
figure['frames'].append(frame)
slider_step = {'args': [
[year],
{'frame': {'duration': 300, 'redraw': False},
'mode': 'immediate',
'transition': {'duration': 300}}
],
'label': year,
'method': 'animate'}
sliders_dict['steps'].append(slider_step)
figure['layout']['sliders'] = [sliders_dict]
iplot(figure, config=config)
I hope this helps you resolve your issue, the slider looks great :)

Categories