Logging list of wandb.Plotly not working

Hi, I am trying to log multiple connected plots similar to using images, as shown in the documentation:

examples = []
for i in range(3):
 pixels = np.random.randint(low=0, high=256, size=(100, 100, 3))
 image = wandb.Image(pixels, caption=f"random field {i}")
 examples.append(image)
wandb.log({"examples": examples})

Trying this with wandb.Plotly instead of wandb.Image:

plots = []
for i in range(3):
 fig = create_plotly_plot(index=i)
 plot = wandb.Plotly(fig)
 plots.append(plot)
wandb.log({"examples": plots})

results in an error in the UI:

Selected runs are not logging media for the key examples, but instead are logging values of type list.

If examples is never supposed to be a media type, please delete this panel and create the proper panel type manually.

How can I log a list of plots similar to a list of images?

Hi @mbp thanks for writing in! Would it work for you to add a slider instead for your Plotly figures as follows:

import plotly.graph_objects as go
import numpy as np

for i in range(3):
    x = np.linspace(0, 10, 100)
    y = np.sin(x) + np.random.normal(0, 0.1, 100)
    fig = go.Figure(data=go.Scatter(x=x, y=y))
    plot = wandb.Plotly(fig)
    wandb.log({"examples_2": plot}, step = i)

Another alternative would be to convert the Plotly to html and add them in a wandb.Table, for example:

# Create a table
table = wandb.Table(columns = ["plotly_figure"])
for i in range(3):
    x = np.linspace(0, 10, 100)
    y = np.sin(x) + np.random.normal(0, 0.1, 100)
    fig = go.Figure(data=go.Scatter(x=x, y=y))

    # Create path for Plotly figure
    path_to_plotly_html = "./plotly_figure.html"
    # Write Plotly figure to HTML
    fig.write_html(path_to_plotly_html, auto_play = False) 
    # Add Plotly figure as HTML file into Table
    table.add_data(wandb.Html(path_to_plotly_html))

wandb.log({"examples_3": table})

Would any of these options work for your use case?

1 Like

Thank you for your reply. When doing it this way the plots do not show up in the UI at all, unfortunately. I can see them in the files section unter root/media/plotly but they cannot be added to the charts section.

By chance, I tried to log the plots one by one without the step=i part and then they showed up in the charts section with a slider. Could you clarify if that is the intended way to do it maybe?

Thank you!

Hi @mbp thanks for the update, could you please try to Add Panel > Plotly and then add in media keys the key you had used to log the plots (for instance in the code snippet above that would be examples_2). Would this work for you?

Hi @thanos-wandb, thanks for your reply. I’m sorry that I did not mention it explicitly but I have tried to add it manually before and the problem is, that the key does not exist in the backend. Here is an excerpt from my code:

_fs = self.log_pred_probs(
     y_train_pred_prob, y_test_pred_prob, threshold=0.5, n_plots=20
)
for i, _f in enumerate(_fs):
     _pf = wandb.Plotly(_f)
     run.log({"prediction_probabilities": _pf}, step=i)

And the files in the files section:

But when adding a plot, the media key does not exist:

Manually specifying the key does not work at all.

Hi @mbp thanks for the additional details, this shouldn’t be the expected behaviour. Are you logging in our SaaS (wandb.ai) or in a local W&B instance? If the former could you please send us a link to your Workspace (or email it to support@wandb.com in case you don’t want to publicly share), or in the latter case please provide us with your Local/Server version (found from <host-url>/settings page).

Hi @thanos-wandb, it is a local setup (Docker) and the version from /settings is

W&B Local 0.30.0

However, this was tested with 0.29.0 as I have since upgraded the version.

Hi @mbp thanks for the additional details, that’s important to know you’re on a self-hosted instance. I have tested it as well though in a 0.30.0 deployment and it worked for me. Could you please try the following code again (in a completely new project)?

import wandb

import plotly.graph_objects as go
import numpy as np

wandb.init(project='plotly')

for i in range(3):
    x = np.linspace(0, 10, 100)
    y = np.sin(x) + np.random.normal(0, 0.1, 100)
    fig = go.Figure(data=go.Scatter(x=x, y=y))
    plot = wandb.Plotly(fig)
    wandb.log({"examples_2": plot}, step = i)

wandb.finish()

Please let me know if this still won’t work for you. I will then try to reproduce if the issue occurs because you logged the data in 0.29.0 and then you upgraded to 0.30.0.

Hi @thanos-wandb, thank you for your reply. I can confirm that your example yields the expected result and the slider is shown with the step values.

I am thinking out loud here but what if:

  • running multiple agents messes up the step value since in my experiments with multiple agents, the step value shown in the dashboard is usually not contiguous, i.e. instead of {1, 2, 3, ..., n} the steps are e.g. {54, 78, 90, ..., m}.

What do you think?

  • setting the step manually, overwrites the automatic value and allows multiple agents to set the same step value

You can see this in my screenshot above, where three files with the name prediction_probabilities_154_xxxx.plotly.json exist; note the same step=154 value.

What do you think?

Hi @mbp sorry for the late response here, but glad to hear that the previous code snippet worked for you. Regarding the steps issue, I can see that you have indeed created three plots at 154th iteration. Could you please try to enforce commiting the global step by adding the argument as follows:

wandb.log({"examples_2": plot}, step = i, commit=True)

You could also try to omit the step argument in that case.

Regarding the multiple parallel agents, I don’t see how you could create a conflict since each one would log the plotly files in a different run. Could you please provide us with a code snippet to try and reproduce that behavior?

Hi @thanos-wandb , thanks for the follow-up. I created the followin MWE that showcases the behavior I was referring to:

import wandb
import numpy as np
import plotly.graph_objects as go


def func():
    wandb.init()

    plots = []
    for i in range(3):
        x = np.linspace(0, 10, 100)
        o = np.random.randint(0, 2 * np.pi)
        y = np.sin(x + o) + np.random.normal(0, 0.1, 100)
        fig = go.Figure(data=go.Scatter(x=x, y=y))
        plot = wandb.Plotly(fig)
        plots.append(plot)

    wandb.log({"error": o})
    wandb.log({"examples": plots})

    wandb.finish()


wandb.login(
    key="",
    host="",
    relogin=True,
)

SWEEP_CONFIG = {
    "method": "random",
    "name": "my_config",
    "metric": {"goal": "minimize", "name": "error"},
    "parameters": {
        "param1": {"values": [8, 16, 32]},
    },
}

sweep_id = wandb.sweep(sweep=SWEEP_CONFIG, project="plotly")
agent = wandb.agent(
    sweep_id=sweep_id,
    function=func,
    project="plotly",
    count=5,
)

It plots three Plotly figures during each run. They are added to a local list and then logged all at once. Unfortunately, instead of showing in the web interface, the error message mentioned in the first post appears. You can see the files available in the “Files” section and all have the same step value, as discussed.

It doesn’t seem to be caused by multiple agents, since this also happens when running the above snippet only once (i.e., not in parallel).

Adding commit=True in this MWE does not have any effect, though I didn’t test it with logging each step separately inside the loop (will do this later).

Hi @mbp thanks a lot for the update, and the provided code. Could you please try also logging them inside the loop with the step and commit arguments, would this work for you?

Hi @mbp just checking in here to see if this worked for you when executing this within a loop? thanks!

Hi @thanos-wandb, thank you for your reply. It works for the MWE I provided. But if I add a second plot it will only show the first one (key examples) and skip/ignore the second one (examples2). It is also not possible to add the plot manually, the key examples2 does not exist in the list.

def func():
    wandb.init()

    for i in range(3):
        x = np.linspace(0, 10, 100)
        o = np.random.randint(0, 2 * np.pi)

        y = np.sin(x + o) + np.random.normal(0, 0.1, 100)
        fig = go.Figure(data=go.Scatter(x=x, y=y))
        plot = wandb.Plotly(fig)
        wandb.log({"examples": plot}, step=i, commit=True)

        y2 = np.sin(x + o) + np.random.normal(0, 0.1, 100)
        fig2 = go.Figure(data=go.Scatter(x=x, y=y2))
        plot2 = wandb.Plotly(fig2)
        wandb.log({"examples2": plot2}, step=i, commit=True)

    wandb.log({"error": o})

    wandb.finish()

I can see the files being present though:

Thanks so much @mbp for the reproducible example, I could see the issue indeed. In this case, it’s resolved if you omit the commit=True argument. The previously shared example would work with this argument because it had only one wandb.log() call. Could you please try again without the commit?

1 Like

Hi @mbp just checking in here to see if it eventually worked for you without the commit argument? Thank you!

Hi @mbp since we haven’t heard back from you, I will go ahead and close this ticket for now. However, please feel free to reopen it if the issue persists for you and we would be glad to keep investigating.

I just wanted to share that this was the solution. commit=True solved the problem for me.

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.