I have used graphviz_chart() function to display graphviz charts but it does not accept Node positions (x,y) I tried to search around but did not find solution anywhere. below is my code. some one know such solutions.
graph.node(v, label=label, shape='record', pos=f'{x},-{y}!')
it display graph but only in sequential order. does not position the node where I fix it.
Sadly, this is an old bug/limitation of st.graphviz_chart
In short, a different engine is required by graphviz to render nodes in fixed positions (check pos | Graphviz for details), however, none of them are supported by st.graphviz_chart
.
Related topic:
1 Like
I used neato which supports positioning. any idea shall I switch to anyother graph libraray? I need to draw flow chart at specified positions.
I’d export the graph as an image and then display that image using st.image
(which is what st.graphviz_chart
does anyway iinw). Check the graphviz.pipe
and graphviz.render
methods from API Reference — graphviz 0.20.1 documentation.
Here a small example:
import streamlit as st
import graphviz
from io import BytesIO
engines = ['circo', 'dot', 'fdp', 'neato', 'osage', 'patchwork', 'sfdp', 'twopi']
shapes = ['note', 'egg', 'star', 'house', 'box']
"# Alternative to `st.graphviz_chart`"
cols = st.columns([1,2])
with cols[0]:
engine = st.selectbox("Engine:", engines)
shape = st.selectbox("Shape:", shapes)
dpi = st.slider("dpi:", 10, 600, 200, 10)
## Create graph
graphviz.set_default_engine(engine=engine)
g = graphviz.Digraph('Round-table', engine=engine)
## Global graph attributes
g.graph_attr['pin'] = 'true' # <-- Fixed position of nodes
g.graph_attr['dpi'] = f'{dpi}' # <-- Sets the PNG resolution
g.graph_attr['rankdir'] = 'LR' # <-- Left to right order
g.graph_attr['bgcolor'] = 'transparent'
## Global node attributes
g.node_attr['shape'] = shape
g.node_attr['fillcolor'] = 'lightgrey'
g.node_attr['style'] = 'filled'
## Global node attributes
g.edge_attr['color'] = 'blue'
## Add nodes and edges
for i in range(4):
g.node(str(i), label=f"{shape} {i}", pos=f'{i}, -{i}!')
if i < 3:
g.edge(f"{i}", f"{i+1}")
## Export as image
with BytesIO() as f:
f.write(g.pipe(format='png', engine=engine))
with cols[1]:
st.image(f, use_column_width=True, caption="Awesome graph!")
1 Like