question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

matplotlib globals cause problems with `pyplot()` if multiple sessions

See original GitHub issue

I’m not actually sure if this is a documentation suggestion or bug report or what, but it seems worth noting:

I run this with streamlit (0.52.2):

import time
import streamlit as st
import matplotlib.pyplot as plt

while True:
    plt.scatter([1, 2, 3], [1, 2, 3])
    st.pyplot()
    time.sleep(.2)

I open one browser window, and everything is as expected (I see a long series of plots). If I view the app in another browser tab, then one of the tabs gets this traceback:

IndexError: list index out of range
Traceback:
  File "/Users/davidchudzicki/.virtualenvs/streamlit/lib/python3.6/site-packages/streamlit/ScriptRunner.py", line 324, in _run_script
    exec(code, module.__dict__)
  File "/Users/davidchudzicki/streamlit_end_code_block/b.py", line 8, in <module>
    st.pyplot()
  File "/Users/davidchudzicki/.virtualenvs/streamlit/lib/python3.6/site-packages/streamlit/__init__.py", line 152, in wrapped_method
    return method.__get__(dg)(*args, **kwargs)
  File "/Users/davidchudzicki/.virtualenvs/streamlit/lib/python3.6/site-packages/streamlit/DeltaGenerator.py", line 135, in wrapped_method
    return dg._enqueue_new_element_delta(marshall_element, delta_type, last_index)
  File "/Users/davidchudzicki/.virtualenvs/streamlit/lib/python3.6/site-packages/streamlit/DeltaGenerator.py", line 392, in _enqueue_new_element_delta
    rv = marshall_element(msg.delta.new_element)
  File "/Users/davidchudzicki/.virtualenvs/streamlit/lib/python3.6/site-packages/streamlit/DeltaGenerator.py", line 133, in marshall_element
    return method(dg, element, *args, **kwargs)
  File "/Users/davidchudzicki/.virtualenvs/streamlit/lib/python3.6/site-packages/streamlit/DeltaGenerator.py", line 1305, in pyplot
    pyplot.marshall(element, fig, clear_figure, **kwargs)
  File "/Users/davidchudzicki/.virtualenvs/streamlit/lib/python3.6/site-packages/streamlit/elements/pyplot.py", line 57, in marshall
    fig.savefig(image, **kwargs)
  File "/Users/davidchudzicki/.virtualenvs/streamlit/lib/python3.6/site-packages/matplotlib/pyplot.py", line 723, in savefig
    fig.canvas.draw_idle()   # need this if 'transparent=True' to reset colors
  File "/Users/davidchudzicki/.virtualenvs/streamlit/lib/python3.6/site-packages/matplotlib/backend_bases.py", line 1914, in draw_idle
    self.draw(*args, **kwargs)
  File "/Users/davidchudzicki/.virtualenvs/streamlit/lib/python3.6/site-packages/matplotlib/backends/backend_agg.py", line 388, in draw
    self.figure.draw(self.renderer)
  File "/Users/davidchudzicki/.virtualenvs/streamlit/lib/python3.6/site-packages/matplotlib/artist.py", line 38, in draw_wrapper
    return draw(artist, renderer, *args, **kwargs)
  File "/Users/davidchudzicki/.virtualenvs/streamlit/lib/python3.6/site-packages/matplotlib/figure.py", line 1709, in draw
    renderer, self, artists, self.suppressComposite)
  File "/Users/davidchudzicki/.virtualenvs/streamlit/lib/python3.6/site-packages/matplotlib/image.py", line 135, in _draw_list_compositing_images
    a.draw(renderer)
  File "/Users/davidchudzicki/.virtualenvs/streamlit/lib/python3.6/site-packages/matplotlib/artist.py", line 38, in draw_wrapper
    return draw(artist, renderer, *args, **kwargs)
  File "/Users/davidchudzicki/.virtualenvs/streamlit/lib/python3.6/site-packages/matplotlib/axes/_base.py", line 2607, in draw
    self._update_title_position(renderer)
  File "/Users/davidchudzicki/.virtualenvs/streamlit/lib/python3.6/site-packages/matplotlib/axes/_base.py", line 2548, in _update_title_position
    ax.xaxis.get_ticks_position() in choices):
  File "/Users/davidchudzicki/.virtualenvs/streamlit/lib/python3.6/site-packages/matplotlib/axis.py", line 2146, in get_ticks_position
    self._get_ticks_position()]
  File "/Users/davidchudzicki/.virtualenvs/streamlit/lib/python3.6/site-packages/matplotlib/axis.py", line 1833, in _get_ticks_position
    minor = self.minorTicks[0]

If I do this instead, there are no problems:

import time
import streamlit as st
import matplotlib.pyplot as plt

while True:
    fig, ax = plt.subplots()
    ax.scatter([1, 2, 3], [1, 2, 3])
    st.pyplot(fig)
    time.sleep(.2)

Not too surprising. (Seems hard to correctly support the matplotlib global objects…) But maybe it’s worth adding warning? (Or even eventually deprecating the no-argument pyplot.)

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Reactions:1
  • Comments:9 (3 by maintainers)

github_iconTop GitHub Comments

2reactions
dchudzcommented, Apr 14, 2020

Yeah. For what it’s worth, your Option 1 seems right to me.

I was initially a little put off from Streamlit when I saw this error in an app someone tweeted. It took me some time to realize that the problem was limited to matplotlib global state, and not a deeper issue with Streamlit itself.

If you stop supporting the global-state API you’ll avoid that kind of perception.

1reaction
jrhonecommented, Apr 7, 2020

Sorry, should have mentioned it’s a private link.

We’re leaning towards allowing the functionality and displaying a warning.

Read more comments on GitHub >

github_iconTop Results From Across the Web

python global variable error with multiple functions
Your problem is that you are sharing a variable in Process and not in Multiprocess pool. When you use global x it can...
Read more >
Initialization, Finalization, and Threads — Python 3.11.1 ...
Python has variables for the global configuration to control different features and options. By default, these flags are controlled by command line options....
Read more >
Common Mistakes When Dealing with Multiple Python Files
When you create a variable (not within a function) in a Python ... However, global variables are not shared across different Python files....
Read more >
How to manage Python environments: Global vs Virtual
Global environment corruption occurs all too frequently. Virtual Python environments are better, but need improvement.
Read more >
Speed Up Your Python Program With Concurrency
local() is in the threading module to specifically solve this problem. It looks a little odd, but you only want to create one...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found