Plotly - how do I highlight the path to a node on hover? - python

I have a graph that looks like this:
The segment of code that generates the graph looks something like this:
import sys
import os
import numpy
import itertools
from lxml import etree
import lxml.html
import re
import networkx as nx
import matplotlib.pyplot as plt
import pygraphviz
from networkx.drawing.nx_agraph import graphviz_layout
import plotly.graph_objects as go
G = nx.DiGraph()
#nodes and edges added around here
pos=graphviz_layout(G, prog='dot')
edge_trace = go.Scatter(
x=edge_x, y=edge_y,
line=dict(width=0.5, color='#888'),
hoverinfo='none',
mode='lines')
node_trace = go.Scatter(
x=node_x, y=node_y,
mode='markers',
hoverinfo='text',
marker=dict(size=10,line_width=2)
)
node_trace.marker.color = color_list
node_trace.text = node_text
config = dict({'scrollZoom': True})
fig = go.Figure(data=[edge_trace, node_trace],
layout=go.Layout(
title='Comparison Results: ',
titlefont_size=16,
showlegend=False,
hovermode='closest',
margin=dict(b=80,l=10,r=10,t=40),
annotations=[ dict(
text="",
showarrow=False,
xref="paper", yref="paper",
x=0.005, y=-0.002 ) ],
xaxis=dict(showgrid=False, zeroline=False, showticklabels=False),
yaxis=dict(showgrid=False, zeroline=False, showticklabels=False))
)
fig.update_layout(dragmode='pan')
fig.show(config=config)
How do I make it so that when I hover over a node, the path all the way to the root node is highlighted?
Any help is much appreciated. Thanks in advance!

Related

Setting longitude and latitude range for mapbox map

I am trying to mark some points on a map. But I would like to zoom in automatically. So I use the following code which works perfectly fine for go.Scattergeo plot.
import pandas as pd
import plotly.express as px
import plotly.graph_objects as go
margin = 0.002
fig.update_layout(
title = 'Something',
autosize=False,
width=800,
height=600,
geo = dict(
# projection_scale=8000, #this is kind of like zoom
lonaxis = dict(
range= [ df['longitude'].min()-margin, df['longitude'].max()+margin ],
dtick = 5
),
lataxis = dict (
range= [ df['latitude'].min()-margin, df['latitude'].max()+margin ],
dtick = 5
)
)
)
But when change the plot to mapbox, the lataxis and lonaxis seem not working anymore.
# fig = px.scatter_mapbox(df,
# lat="latitude",
# lon="longitude",
# color="rssi",
# color_continuous_scale=px.colors.cyclical.IceFire)
fig = go.Figure(go.Scattermapbox(
lon = df['longitude'],
lat = df['latitude'],
mode = 'markers',
marker = dict(
autocolorscale = False,
colorscale = 'icefire',
color = df['rssi'],
)))
fig.update_layout(mapbox_style="open-street-map")
Any idea how can make it work? Or how can zoom in and center graph? Any help is appreciated.

Is there a way to use ONE Plotly drop down button to interact with data as well as a plot?

I am trying to showcase a scatter plot as well as the data for the the plot side by side in jupyter. I wish to add a plotly button (dropdown) that will show the filtered data as well as the corresponding scatter plot. Is this possible WITHOUT USING ipywidgets, using plotly dropdowns?
I was able to build two separate plots for data and scatter plot with dropdowns but cannot combine them together. Following is the code I tried. Here the dropdown only interacts with the table, the scatter plot is not updating.
import plotly.express as px
import plotly.graph_objects as go
import numpy as np
import pandas as pd
df = px.data.iris()
species = sorted(set(df['species']))
#fig=go.Figure()
default_species = "setosa"
df_default = df[df['species']==default_species]
fig = make_subplots(
rows=1, cols=2,
shared_xaxes=True,
horizontal_spacing=0.02,
specs=[[{"type": "scatter"},{"type": "table"}]]
)
fig.add_trace(
go.Scatter(
x=df_default["sepal_length"],
y=df_default["sepal_width"],
mode="markers"
),
row=1, col=1
)
fig.add_trace(
go.Table(
header=dict(
values=["sepal<br>length","sepal<br>length","petal<br>length","petal<br>width","species","species<br>id"],
font=dict(size=10),
align="left"
),
cells=dict(
values=[df_default[k].tolist() for k in df_default.columns],
align = "left")
),
row=1, col=2
)
buttons = []
for s in species:
s_data = df[df['species']==s]
buttons.append(dict(
method='restyle',
label=s,
visible=True,
args=[
{'values':[["sepal<br>length","sepal<br>length","petal<br>length","petal<br>width","species","species<br>id"]],
'cells':[dict(values=[s_data[k].tolist() for k in s_data.columns],align = "left")]},
{'y':[s_data["sepal_width"]],
'x':[s_data['sepal_length']],
'type':'scatter',
'mode':'markers'}
]
))
#fig.update_layout(width=1500, height=500)
# some adjustments to the updatemenus
updatemenu = []
your_menu = dict()
updatemenu.append(your_menu)
updatemenu[0]['buttons'] = buttons
updatemenu[0]['direction'] = 'down'
updatemenu[0]['showactive'] = True
updatemenu[0]['active'] = species.index(default_species)
updatemenu[0]['x'] = 0
updatemenu[0]['xanchor'] = 'left'
updatemenu[0]['y'] = 1.2
updatemenu[0]['yanchor'] = 'top'
# add dropdown menus to the figure
fig.update_layout(showlegend=False,
updatemenus=updatemenu,
xaxis_title="Sepal_Length",
yaxis_title="Sepal_Width"
)
fig.show()
I do not want to use ipywidgets.
The code that worked for me: Editing hope it helps some one
## Create Combination of Scatter Plot and Plotly Tables with interactive Static HTML
import plotly.express as px
import plotly.graph_objects as go
from plotly.subplots import make_subplots
import numpy as np
import pandas as pd
df = px.data.iris()
species_list = sorted(set(df['species']))
# --- function ---
def make_multi_plot(df1, item_list):
fig = make_subplots(rows=1,
cols=2,
#shared_xaxes=True,
#vertical_spacing=0.2,
specs = [[{}, {"type": "table"}]]
)
for item_id in item_list:
#print('item_id:', item_id)
trace1 = go.Scatter(
x=df1.loc[df1.species.isin([item_id])].sepal_length,
y=df1.loc[df1.species.isin([item_id])].sepal_width,
mode='markers',
name = str(item_id)
)
fig.append_trace(trace1, 1, 1)
trace2 = go.Table(
columnorder = [1,2,3,4,5,6],
columnwidth = [2,2,2,2,4,2],
header=dict(
values = ["sepal<br>length","sepal<br>length","petal<br>length","petal<br>width","species","species<br>id"],
font = dict(size=10),
align = "left"
),
cells = dict(
values = [df1[df1.species.isin([item_id])][k].tolist() for k in df1[df1.species.isin([item_id])].columns[:]],
align = "left"
)
)
fig.append_trace(trace2,1,2)
Ld = len(fig.data)
#print(Ld)
Lc = len(item_list)
for k in range(2, Ld):
fig.update_traces(visible=False, selector=k)
def create_layout_button(k, item_id):
#print(k, item_id)
visibility = [False]*2*Lc
for tr in [2*k, 2*k+1]:
visibility[tr] = True
#print(visibility)
return dict(label = item_id,
method = 'restyle',
args = [{'visible': visibility,
'title': item_id
}])
#updatemenu[0]['x'] = 0
#updatemenu[0]['xanchor'] = 'left'
#updatemenu[0]['y'] = 1.2
#updatemenu[0]['yanchor'] = 'top'
fig.update_layout(
updatemenus=[go.layout.Updatemenu(
active=0,
buttons=[create_layout_button(k, item_id) for k, item_id in enumerate(item_list)],
x=0.5,
y=1.3
)],
#title='Model Raporu',
#template='plotly_dark',
#height=800
xaxis_title="Sepal_Length",
yaxis_title="Sepal_Width"
)
fig.show()
# --- main ---
make_multi_plot(df1=df, item_list=species_list)

Changing line color based on other line's index

I have a out dataframe containing two columns, Actual_Values and Predicted_Values.
I am trying to create a graph:
import pandas as pd
import plotly.graph_objects as go
x_data = out.index
trace1 = go.Scatter(
x=x_data,
y=out['Actual_Values'],
name="Actual Values"
)
trace2 = go.Scatter(
x=x_data,
y=out['Predicted_Values'],
name="Predictions"
)
traces = [trace1, trace2]
layout = go.Layout(
xaxis=dict(
autorange=True
),
yaxis=dict(
autorange=True
)
)
fig = go.Figure(data=traces, layout=layout)
plot(fig, include_plotlyjs=True)
which gives:
however, I need a graph, in which the blue line's changes to some other color from the start of the red line.
Does this help you?
import pandas as pd
import numpy as np
import plotly.graph_objects as go
# Data
n = 150
n_pred = 10
df1 = pd.DataFrame(
{"x": np.arange(n),
"actual_value": np.random.randint(0, 100, n)})
df2 = pd.DataFrame(
{"x": np.arange(n-n_pred, n),
"predicted_value": np.random.randint(0, 100, n_pred)})
# You need Outer join when prediction range is
# larger than actual value one.
df = pd.merge(df1, df2, on="x", how="outer")
idx_min = df[df["predicted_value"].notnull()].index[0]
# Plot
trace1 = go.Scatter(
x=df["x"][:idx_min+1],
y=df['actual_value'][:idx_min+1],
name="Actual Values",
line=dict(color="blue")
)
trace2 = go.Scatter(
x=df["x"][idx_min:],
y=df['actual_value'][idx_min:],
name="Actual Values",
mode="lines",
line=dict(color="green"),
showlegend=False
)
trace3 = go.Scatter(
x=df["x"],
y=df['predicted_value'],
name="Predicted Values",
line=dict(color="red")
)
traces = [trace1, trace2, trace3]
layout = go.Layout(
xaxis=dict(
autorange=True
),
yaxis=dict(
autorange=True
)
)
fig = go.Figure(data=traces, layout=layout)
fig.show()

Placing plotly graphics into a leaflet

Im using the Plotly library for an interactive map in python. However, when you use this library it opens it up in chrome when I want to place the figure onto a leaflet to be used in TKinter
from tkinter import *
import csv
import sys
import plotly.graph_objects as go
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
mapbox_access_token = "pk.eyJ1IjoiY21jY3Vza2VyMTMyMiIsImEiOiJja254YjA5emEwb21rMnB0Z3Nib285OGNkIn0.PL7Nx-Q1XgSO5PBSdI2w2Q"
fig = go.Figure(go.Scattermapbox(
lat=['54.1533'],
lon=['-6.0663'],
mode='markers',
marker=go.scattermapbox.Marker(
size=14
),
text=['Mournes'],
))
fig.update_layout(
hovermode='closest',
mapbox=dict(
accesstoken=mapbox_access_token,
bearing=0,
center=go.layout.mapbox.Center(
lat=54,
lon=-6
),
pitch=0,
zoom=9
)
)
fig.show()
f = fig

How to add a horizontal scrollbar to the X axis?

I want to add a (horizontal) scrollbar to the X axis, because the number of points is large. How can I do it?
trace0 = go.Scatter(
x = x1_values,
y = y1_values,
name = "V1"
)
data = [trace0]
layout = dict(title = title,
xaxis = dict(tickmode='linear', tickfont=dict(size=10)),
yaxis = dict(title = "Title")
)
fig = dict(data=data, layout=layout)
iplot(fig)
Using plotly you can add a rangeslider using fig['layout']['xaxis']['rangeslider'] with functionality that exceeds that of a scrollbar:
Plot:
Code:
Here's an example using some random data in an off-line Jupyter Notebook.
# imports
from plotly.offline import download_plotlyjs, init_notebook_mode, plot, iplot
from IPython.core.display import display, HTML
import plotly.figure_factory as ff
import plotly.graph_objs as go
import pandas as pd
import numpy as np
# setup
display(HTML("<style>.container { width:35% !important; } .widget-select > select {background-color: gainsboro;}</style>"))
init_notebook_mode(connected=True)
np.random.seed(1)
# random time series sample
df = pd.Series(np.random.randn(1000),index=pd.date_range('1/1/2000', periods=1000)).cumsum().to_frame()+100
df.columns = ['Series1']
# trace / line
trace1 = go.Scatter(
x=df.index,
y=df['Series1'],
name = "AAPL High",
line = dict(color = 'blue'),
opacity = 0.4)
# plot layout
layout = dict(
title='Slider / Scrollbar',
xaxis=dict(
rangeselector=dict(
buttons=list([
dict(count=1,
label='1m',
step='month',
stepmode='backward'),
dict(count=6,
label='6m',
step='month',
stepmode='backward'),
dict(step='all')
])
),
rangeslider=dict(
visible = True
),
type='date'
)
)
# plot figure
data = [trace1]
fig = dict(data=data, layout=layout)
iplot(fig)
For more details take a look here.

Categories