Using virtual WebGL in python (outside of notebooks)

Hi all :))

I’m creating some figures with a lot of 3d surface figures, and because of the limitation on WebGL contexts, I can only show 16 of them in e.g. chrome.

I’ve found a plotly support page where they mention that it’s possible to use virtual WebGL to circumvent this issue, but I don’t understand how to do this in python. They mention how it can be done in a jupyter notebook, but I need to be able to do it outside of notebooks. The tutorial page is here: https://plotly.com/python/performance/#multiple-webgl-contexts. There’s also an issue here where it is mentioned (https://github.com/plotly/plotly.js/issues/2333) but it is again only for jupyter notebooks.

Does anyone know how to do this?

Cheers,

Aster

hi @Aster_Stoustrup,

Thx for sharing your question and glad to see that you’re exploring Plotly!

Actually, you don’t need Jupyter to use WebGL mode. Plotly Express is just a Python wrapper around Ployly.js, which generates the same figures regardless of environment. The examples in the official docs often use Jupyter for convenience, but you can fully use WebGL in Dash, standalone python scripts, or any python environment that supports Plotly.

br

Hi @stu and thanks for replying! :slight_smile:

Yes, I believe I’m already using WebGL, but I need to use this virtual WebGL thing, so that the browser will only register one WebGL context, and thus stop restricting me from having more than 16 subplots open at a time.

Do you know how to do that? They talk about it in the tutorial page I linked and mention a .js script, but they don’t explicitly say how to use it outside of jupyter.

hi @Aster_Stoustrup ,

It seems like you might be hitting some browser limits on the WebGL context. You may want to try pasting your code here so we can take a closer look together, the fix might not have to rely on a specific library to get what you want.

As for the virtual-webgl.js you mentioned, in Dash you can include it via the external_js property and use it alongside clientside-callbacks.

Examples:

from dash import Dash, html


# external JavaScript files
external_scripts = [
    'https://www.google-analytics.com/analytics.js',
    {'src': 'https://cdn.polyfill.io/v2/polyfill.min.js'},
    {
        'src': 'https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.core.js',
        'integrity': 'sha256-Qqd/EfdABZUcAxjOkMi8eGEivtdTkh3b65xCZL4qAQA=',
        'crossorigin': 'anonymous'
    }
]

# external CSS stylesheets
external_stylesheets = [
    'https://codepen.io/chriddyp/pen/bWLwgP.css',
    {
        'href': 'https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css',
        'rel': 'stylesheet',
        'integrity': 'sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO',
        'crossorigin': 'anonymous'
    }
]


app = Dash(__name__,
                external_scripts=external_scripts,
                external_stylesheets=external_stylesheets)

app.layout = html.Div()

if __name__ == '__main__':
    app.run(debug=True)

Hi @stu

Yep, exactly, I’m hitting Google Chrome’s limit for 16 WebGL contexts.

Cool that it can be done in dash, but I would like to be able to do it for a normal plotly figure.

I’m using make_subplots to make a figure with ‘specs=[[{‘type’: ‘surface’} for c in range(columns)] for r in range(rows)]’.

Then I add a go.Surface and a go.Scatter3d to the subplots.

Everything works great when I have less than 16 subplots, but when I add more, I run into this WebGL context limit. I would like to get past that limit somehow and the suggested solution seems to be using Virtual WebGL.

Hope that adds some clarity :slight_smile: