ChrisDelClea / streamlit-agraph

A Streamlit Graph Vis
MIT License
387 stars 52 forks source link

Node SVG doesn't handle local files. #14

Closed nfmcclure closed 2 years ago

nfmcclure commented 3 years ago

Hi- thanks so much for this repo and all your work.

I've been using the 'svg' property of the nodes to change the appearance of the nodes. This is really helpful to visually show multiple different node types.

Sometimes, the png URL that I provide for the svg doesn't respond all the time upon rerun. When that happens, the streamlit app quits. I wanted to host a png file locally and use the filepath instead of a URL. But that just doesn't work.

For example in the ego_graph.py, I can change the following line: ego-graph.py#L38 to:

nodes = [Node(id=i, label=str(i), size=200, svg='https://icons.iconarchive.com/icons/findhold/karate/512/karate-ready-icon.png') for i in hub_ego.nodes]

And get a nice graph with "karate kid" icons for nodes.

But if I download the png to the base folder and do:

nodes = [Node(id=i, label=str(i), size=200, svg='karate-ready-icon.png') for i in hub_ego.nodes]

I get broken link images instead.

I don't know too much JS/React/D3, but I'm willing to work on this, if you can point me in the right direction.

Thanks!

ChrisDelClea commented 3 years ago

Hi @nfmcclure,

I wanted to do the same and ran into the same issue. Normally, you would define a new folder in your streamlit project called images or assets. Inside that folder you can put all the images and reference e.g.:

img = Image.open(f"./images/base_filename")
st.image(img)

That should work fine for running it locally. However, if you want to deploy it on streamlit sharing, you had to make:

  1. the image folder gets uploaded
  2. make sure that the relative paths to the folder are right

So far, I couldn't figure out what them hinders the upload. If you find something out, let me know.

zjorgensenbits commented 2 years ago

In case anyone still needs this, here is one way to do it. Open the image file and convert it to a base64 encoded string and then pass that string as the svg parameter, i.e.,

svg = "data:image/svg+xml;base64,"
with open("test.svg", "rb") as img_file:
    svg = svg + base64.b64encode(img_file.read()).decode('UTF-8')