Clearing the Matplotlib plot without clearing slider - python

I'm currently creating an application where I need to update matplotlib graphs. I'm stuck at following step.
I have a scatter plot and slider in the same figure. Upon changing the slider value, I need to clear the scatter plot without clearing the slider. Following is the code I implemented, but it does not clear the plot.
The .clf() function removes both the slider and scatter plot. Is there a way I could remove only the plot without impacting the slider?
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import Slider
X1=np.arange(10)
Y1=np.arange(10)
Z1=np.arange(10)
fig,ax=plt.subplots()
ax=plt.scatter(X1,Y1,Z1)
axSlider1=plt.axes([0.3,0.9,0.3,0.05])
Slder2=Slider(ax=axSlider1,label='Slider',valmin=1,valmax=4,valinit=2)
plt.show()
# Function to clear the scatter plot without effecting slider.
def val_update(val):
plt.cla()
Slder2.on_changed(val_update)

fig,ax=plt.subplots()
Assigned the Axes object to ax - then
ax=plt.scatter(X1,Y1,Z1)
assigns a PathCollection object to ax. So val_update is tying to act on the wrong thing.
This seems to solve the issue you asked about.
X1=np.arange(10)
Y1=np.arange(10)
Z1=np.arange(10)
fig,ax=plt.subplots()
path=plt.scatter(X1,Y1,Z1)
axSlider1=plt.axes([0.3,0.9,0.3,0.05])
Slder2=Slider(ax=axSlider1,label='Slider',valmin=1,valmax=4,valinit=2)
# Function to clear the scatter plot without effecting slider.
def val_update(val):
print(val)
ax.clear()
Slder2.on_changed(val_update)
plt.show()
The Matplotlib Gallery is a good resource you can browse through it looking for features you want and see how they were made. - Like this slider demo
If you think you will be using matplotlib in the future I would recommend working your way through the Introductory tutorials and at least the Artists tutorial

Related

How do I draw borders around a matplotlib plot using object-oriented code?

I would like generate a plot with the coordinate axes in the middle of the plot area. Using matplotlib, I've managed to get as far as is shown in this sample code:
import matplotlib.pyplot as plt
xvalues = [-3,-2,-1,1,2,3]
yvalues = [2,4,-2,-4,1,-1]
fig, ax = plt.subplots()
ax.spines['bottom'].set_position('zero')
ax.spines['left'].set_position('zero')
ax.scatter(xvalues, yvalues)
The problem with using set_position() to move the spines into the middle of the plot area is that this removes them as elements of the plot's border. I'm looking for a way to restore the border lines using object-oriented operations on the Figure and Axes instances fig and ax, respectively.
Please note that I'm interested in manifestly object-oriented code only: operations on fig and ax. This constraint is a part of the question.
I won't accept an answer given in terms of plt or equivalent. I already know how to do that. I'll accept an answer demonstrating that it isn't possible to draw these border lines using only manifestly object-oriented code before I accept an answer using plt.

seaborn in jupyter notebook: why does sns.despine() work for lmplot but not regplot?

Jupyter notebook, using Python 3:
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline
sns.despine()
then
snstest1 = sns.regplot(x="foo", y="bar", data=my_data)
shows a plot with the unwanted border box (i.e., sns.despine() doesn't seem to have affected it).
but:
snstest2 = sns.lmplot(x="foo", y="bar", data=my_data)
shows a plot with the unwanted border box correctly removed.
The only documentation I can find that seems to bear directly on this is the following, from the api docs for regplot:
Understanding the difference between regplot() and lmplot() can be a
bit tricky. In fact, they are closely related, as lmplot() uses
regplot() internally and takes most of its parameters. However,
regplot() is an axes-level function, so it draws directly onto an axes
(either the currently active axes or the one provided by the ax
parameter), while lmplot() is a figure-level function and creates its
own figure, which is managed through a FacetGrid. This has a few
consequences, namely that regplot() can happily coexist in a figure
with other kinds of plots and will follow the global matplotlib color
cycle. In contrast, lmplot() needs to occupy an entire figure, and the
size and color cycle are controlled through function parameters,
ignoring the global defaults.
But I don't fully understand the difference between a "figure" and an "axis." The best guess I can make without knowing the underlying model here is that when these weird global-state-mutating functions built into Seaborn, like despine and (?) set_palette and such, are active, only "figures," not "axes," check that state before rendering? But if that's so, how would I get something that generates an "axis" to plot in accordance with what I've requested?
In short: Call sns.despine after your plotting function.
The longer version:
lmplot creates its own figure. But it does not need despine. It will do it automatically, even without calling sns.despine.
import matplotlib.pyplot as plt
import seaborn as sns
tips = sns.load_dataset("tips")
g = sns.lmplot(x="total_bill", y="tip", data=tips)
plt.show()
This is the reason the code from the question actually seems to work.
However, what is really happening is that if you call sns.despine before any figure is created, it will act on a newly created figure. The code from the question is hence creating two figures. One, which is empty, but also is "despined" and then one which is the lmplot figure and which is "despined" because every lmplot is despined by default.
A regplot is instead created in an axes of a matplotlib figure. If no figure or axes is provided, it will create a new one. This means that sns.despine needs to know which axes to despine. If you call it before anything else, there will again be two figures: One, which is empty, but also is "despined" and then one which is the regplot figure. This figures axes are not "despined", because noone told them so.
So the idea is of course to call sns.despine after creating the plot. You may specify which figure or axes to despine as argument (sns.despine(ax=ax))
import matplotlib.pyplot as plt
import seaborn as sns
tips = sns.load_dataset("tips")
ax = sns.regplot(x="total_bill", y="tip", data=tips)
sns.despine(ax=ax)
plt.show()
but if you only have a single subplot that wouldn't even be necessary. Hence
tips = sns.load_dataset("tips")
sns.regplot(x="total_bill", y="tip", data=tips)
sns.despine()
will work equally well and produce

Do I need a figure? What are they for?

I have begun using matplotlib and I am somewhat confused as to why figures exist. Sometimes I see code where a figure is declared and then a plot is made, and sometimes I see things like this:
import numpy as np
import matplotlib.pyplot as plt
data = np.loadtxt('initial.dat','float')
plt.plot(data[:,0], data[:,1])
plt.xlabel("x (Angstroms)")
plt.ylabel("V (eV)")
plt.savefig('v.png',bbox_inches='tight')
plt.clf()
I read the documentation on figure and plot, but I don't get it. Why do figures exist?
A figure will always exist once you create some plot with matplotlib.
The introductory matplotlib page may help here:
The whole figure. The figure keeps track of all the child Axes, a smattering of ‘special’ artists (titles, figure legends, etc), and the canvas. (Don’t worry too much about the canvas, it is crucial as it is the object that actually does the drawing to get you your plot, but as the user it is more-or-less invisible to you). A figure can have any number of Axes, but to be useful should have at least one.
You can imagine the figure to be the white sheet of paper you draw a plot on. A figure has some size, maybe a background and most importantly it is the container for everything you draw into it. In most cases this will be one or more axes. If there wasn't any figure, there wouldn't be any sheet of paper to draw your plot to (you cannot draw a line in the air).
Even if you haven't explicitely created the figure, it is automatically created in the background.
import matplotlib.pyplot as plt
plt.plot([1,2,3])
# at this point we already have a figure, because the plot needs to live somewhere
# we can get a handle to the figure via
figure = plt.gcf()
Examples of when you explicitely need a figure:
If you want to create a second figure.
plt.plot([1,2,3])
plt.figure(2)
plt.plot([2,4,6])
If you want to set the figure size or other figure parameters.
plt.figure(figsize=(5,4), dpi=72)
If you want to change the padding of the subplot(s).
fig, ax=plt.subplots()
fig.subplots_adjust(bottom=0.2)

multiple graph (not subplot) using python and matplotlib

I would like to plot two or more graphs at once using python and matplotlib. I do not want to use subplot since it is actually two or more plots on the same drawing paper.
Is there any way to do it?
You can use multiple figures and plot some data in each of them. The easiest way of doing so is to call plt.figure() and use the pyplot statemachine.
import matplotlib.pyplot as plt
plt.figure() # creates a figure
plt.plot([1,2,3])
plt.figure() # creates a new figure
plt.plot([3,2,1])
plt.show() # opens a window for each of the figures
If for whatever reason after creating a second figure you want to plot to the first one, you need to 'activate' it via
plt.figure(1)
plt.plot([2,3,1]) # this is plotted to the first figure.
(Figure numbers start at 1)

Empty python plot

I'm running a script remotely on a cluster to generate a scatter plot. I wish to save the plot, but I don't want the plot to be display or a window to come up (as when you execute plt.show() ).
My saved plots are always empty. This is the code that I'm using (below). Any tips would be very helpful. Thanks!
fig = plt.figure()
ax = fig.add_subplot(111)
ax.set_xlim([-1,maxX+1])
ax.set_ylim([0,maxY+1])
ax.set_xlabel('Comparison number (n)', fontsize=18, fontweight='bold')
ax.set_ylabel('Normalized cross correlation score', fontsize=18, fontweight='bold')
ax.scatter(xaxis,yaxis)
plt.savefig('testfig.png')
In order to use avoid showing plot windows (i.e. to do off-screen rendering) you probably want to use a different matplotlib backend.
Before any matplotlib import statements, add
import matplotlib
matplotlib.use('Agg')
and subsequent calls to matplotlib will not show any plot windows.
If your plot file shows an empty axis, then the problem lies in the plotting arguments as calling plot with empty arguments creates an empty axis.

Categories