Matplotlib and Jupyter notebook multiple interactive plots - python

I am facing the following problem: I need two interactive plots to work at the same time on Jupyter, however they are interfering. When I rotate the cell of the first, the second plot stops being interactive and becomes "inline". Other times one of the plots looks like this:
The expected result was something like this
I imagine the problem is in the implementation I made. As you can see below, I use plt.something to put things in the figure (both for plot 1 and plot 2).
I'm using the %matplotlib notebook environment and tried to implement using fig1, ax1 = plt.subplots(). I would like to know if it is possible to do this type of implementation, where there is no conflict between plots? Maybe I am using matplotlib badly, so I would like some suggestions.

Related

Visualizing Python interactive plots outside of Jupyter

I am making some small tests in Jupyter. The user should see two plots, one on the left and one on the right. Than after clicking somewhere on the left plot something on the right plot should happen. For example here a click on the left plot will produce a red dot on the right plot in the same place:
%matplotlib notebook
def onclick(event):
ax.clear()
ax2.clear()
ax.set_xlim(0,10)
ax.set_ylim(0,10)
ax2.set_xlim(0,10)
ax2.set_ylim(0,10)
ax2.plot([event.xdata],[event.ydata],'o',color='red')
ax.figure.canvas.draw_idle()
ax2.figure.canvas.draw_idle()
fig = plt.figure(figsize=(20,10))
ax = fig.add_subplot(121)
ax2 = fig.add_subplot(122)
ax.set_xlim(0,10)
ax.set_ylim(0,10)
ax2.set_xlim(0,10)
ax2.set_ylim(0,10)
cid = fig.canvas.mpl_connect('button_press_event',onclick)
This works, but the visualization in Jupyter is not the best. Is there a way to have this kind of interactive plots working outside of a Jupyter notebook ? Maybe in a window with varying dimensions ? As an example, how would one proceed with the example above ?
You can use plotly and export your plots to html file:
https://plotly.com/python/interactive-html-export/
I think I found a possible simple answer to my needs. Simply put the code in the question in a python script, remove the 'magic' command and insert at the end:
plt.show(block=True)
This way matplotlib will just use a different backend than notebook or inline in Jupiter and plot the figure in a separate window. This window is compatible with the interactive commands from matplotlib. I am not sure about widget compatibility though I will try and update the answer.
Update: I do not think ipywidgets can be used with plt.show() since these are not plotted in an axes, but there are some widgets within matplotlib (matplotlib.widgets) that can be used. Though, the resulting speed in my case is not satisfactory so I would avoid combining matplotlib widgets with matplotlib event catching.

Spyder plots not allowing enough user control

I am running python (3.8) via spyder (4.1.4) on a Windows laptop. I need to plot multiple series on a single graph, then do the usual things like adjusting axis limits, positioning the legend, etc. Spyder will not let me do all of this in one single plot.
For instance, the following produces two different plots:
plt.plot(seriesa,'o')
plt.plot(seriesb,'o')
and so does this:
fig = plt.figure()
ax = fig.add_subplot()
ax.plot(seriesa,'o')
ax.plot(seriesb,'o')
I can get both plots in one graph by doing the entire thing in one command:
fig = plt.figure() ; ax = fig.add_subplot() ; ax.plot(seriesa,'o') ; ax.plot(seriesb,'o')
(which seems like a hack to me, but I'll do whatever works). But then I need to adjust the y axis limits, and the command
ax.set_ylim((0,2000))
has no effect on the plot. And the command
plt.ylim((0,2000))
opens up an entirely new plot.
I tried inline plotting too (unchecking the "Mute inline plotting" menu item), with no improvement.
How do I get the control I need with my plots?
In case anyone is interested, the solution is, before doing any plotting, issue the IPython "magic command":
In [1]: %matplotlib auto
This puts spyder in a state where plots are by default placed in independent windows, as when python is run in a regular shell. Could not find this in spyder documentation. Found it in a similar stack overflow question here.

Matplotlib GUI showing even though I never called plt.show()

I am using the following functions in order...
- plt.figure()
- plt.plot()
- plt.ylim
- plt.xticks()
- figure = plt.gcf()
- figure.set_size_inches()
- plt.savefig()
I just want to save the figure as png, which I've been doing successfully. But the GUI keeps showing up and I am going to generate a bunch of graphs in one script, I don't want the GUI popping up every time one is created and slow my run time.
Does anyone know why it is showing up still?
If you are using a Jupyter Notebook, there are a number of potential solutions posted here.
To summarize, try this to disable inline output from Matplotlib:
import matplotlib as plt
plt.ioff()
Or put this at the start of a cell to prevent it from creating output:
%%capture

plt.show() not showing data instead holding it for next plot (spyder)

I have been using the same setup for quite some time now but suddenly I am no longer allowed to plot more than one graph in a program.
Usually I can plot multiple plots after each other and let the program run through it. It executes the next lines of code after closing the first window. However, recently the first plot is not shown but instead the data is added to the last plot.
I have included a sample code which used to give me two plots but now only one.
import matplotlib.pyplot as plt
import numpy as np
random_num = np.random.randint(0,5,10)
random_num_2 = np.random.randint(0,100,10)
plt.plot(random_num, 'ko')
plt.show()
plt.plot(random_num_2, 'g*')
plt.show()
The first image shows the output from my program. But I would like to have them separated into two plots like Figure 2 and 3 show.
Maybe I should add that I am using Python 3.6 with Spyder 3.2.4. The graphics option is set to display it in Qt5 even though I tried all settings and only 'Inline' shows me the results the way I want it.
Sorry if this is a very simple question. I have tried googling but I only come up with questions about my topic where the way mine works would be the solution not the problem.
#TheresaOtt. I would suggest you create a new figure instance (plt.figure()) for each plot and use only once at the end the plt.show() command.

Matplotlib, Jupyter: Have annotation appearing when hovering over plot

I am trying to create a plot with matplotlib that has tooltip appearing when hovering hover certain elements of the charts. I want to do that in the Jupyter Notebook, with python 3.
I have tried the snippets provided here:
http://matplotlib.org/examples/event_handling/pick_event_demo.html
Possible to make labels appear when hovering over a point in matplotlib?
Is there a matplotlib equivalent of MATLAB's datacursormode?
Matplotlib basemap: Popup box
But none of them work. The plot shows but is not interactive.
I tried with and without the magic %matplotlib inline with no effect.
I of course also modified the print statement when it was without parenthesis.
Is there a specific command or backend to use in order to have the interaction working in Jupyter?
EDIT:
the example working with mpld3 "works" but i would rather stick to the basic matplotlib.
I think you want %matplotlib notebook. This will integrate interactive plots in the notebook.

Categories

Resources