matplotlib globals cause problems with `pyplot()` if multiple sessions
See original GitHub issueI’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:
- Created 4 years ago
- Reactions:1
- Comments:9 (3 by maintainers)
Top 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 >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
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.
Sorry, should have mentioned it’s a private link.
We’re leaning towards allowing the functionality and displaying a warning.