I have a small Django app that produces two different pie charts.
But the labels from the first chart that's displayed reappear in
the second chart.
I'm just using:
plt.pie(...)
plt.savefig(...)
In the same view for two different pie charts using two different
(small) datasets.
Is there some 'clear' or 'reset' method I need to call after the saving of the
plot?
You can leave your code unchanged, and clean your figure by calling clf() after having saved the first plot and before generating the second plot.
By doing so, you are interfacing with matplotlib state-machine. Matplotlib automatically creates figure and axes for you, and you use keep using the same figure.
The alternative is to use matplotlib in a more object-oriented way. You ask matplotlib to create figure and axes object, and then you do all the rest by calling methods of those objects:
fig1,ax1=plt.subplots()
fig2,ax2=plt.subplots()
ax1.pie(...)
ax2.pie(...)
fig1.savefig(...)
fig2.savefig(...)
The usage FAQ here clarifies the two options.
Related
What is the difference between the Axes.plot() and pyplot.plot() methods? Does one use another as a subroutine?
It seems that my options for plotting are
line = plt.plot(data)
or
ax = plt.axes()
line = ax.plot(data)
or even
fig = plt.figure()
ax = fig.add_axes([0,0,1,1])
line = ax.plot(data)
Are there situations where it is preferable to use one over the other?
For drawing a single plot, the best practice is probably
fig = plt.figure()
plt.plot(data)
fig.show()
Now, lets take a look in to 3 examples from the question and explain what they do.
Takes the current figure and axes (if none exists it will create a new one) and plot into them.
line = plt.plot(data)
In your case, the behavior is same as before with explicitly stating the
axes for plot.
ax = plt.axes()
line = ax.plot(data)
This approach of using ax.plot(...) is a must, if you want to plot into multiple axes (possibly in one figure). For example when using a subplots.
Explicitly creates new figure - you will not add anything to previous one.
Explicitly creates a new axes with given rectangle shape and the rest is the
same as with 2.
fig = plt.figure()
ax = fig.add_axes([0,0,1,1])
line = ax.plot(data)
possible problem using figure.add_axes is that it may add a new axes object
to the figure, which will overlay the first one (or others). This happens if
the requested size does not match the existing ones.
There is essentially no difference. plt.plot will at some point (after making sure that there is a figure and an axes available to plot to) call the plot function from that axes instance.
So the main difference is rather at the user's side:
do you want to use the Matlab-like state machine approach, which may save some lines of code for simple plotting tasks? Then use pyplot.
do you want to have full control over the plotting using the more pythonic object oriented approach? Then use objects like axes explicitely.
You may want to read the matplotlib usage guide.
Pyplot's plotting methods can be applied to either the Pyplot root (pyplot.plot()) or an axes object (axes.plot()).
Calling a plotting function directly on the Pyplot library (pyplot.plot()) creates a default subplot (figure and axes). Calling it on an axes object (axes.plot()) requires that you to have created your own axes object already and puts the graph onto that customized plotting space.
While pyplot.plot() is easy to use, you have more control over your space (and better able to understand interaction with other libraries) if you create an axes object axes.plot().
Axes.plot() returns an axes object. Every axes object has a parent figure object. The axes object contains the methods for plotting, as well as most customization options, while the figure object stores all of the figure-level attributes and allow the plot to output as an image.
If you use pyplot.plot() method and want to start customizing your axes, you can find out the name of the default axes object it created by calling pyplot.gca() to "get current axes."
python plt.plot(): it will create many default subplots, will save many lines of code and is easy to understand.
Axes.plot(): using an axes object will give you a better ability to customize your plot space.
If this is still relevant, Matplotlib's official website has a clear answer on this issue. Go to "The object-oriented interface and pyplot interface".
This section clearly answers the question. Using 'fig, ax', i.e., object-oriented approach gives one more control for customizing our plot. Using 'pyplot', on the other hand leaves us with less control over our plot but the advantage is that it saves us from writing more lines of code and is easier and handy when dealing with single plot.
Official documentation of Matplotlib suggests that "which approach to use is solely an individual's choice and there is no preference of one over other. However, it is good to stick to one approach to maintain consistency."
I am working on a project where I am generating hundreds of plots using the matplotlib module in Python. I want to put these plots in a pptx using the python-pptx module, let's say four plots on a slide without storing these plots on the local disk.
To overcome the storing problem I am using the BytesIO python module, which stores the plots inside the buffer, and then send these plots to the pptx.
The major issue that I am facing is the overlapping of the plots.
Question is how to send these plots serially to pptx so that we can avoid the overlapping?
Screenshot of pptx generated
I have added a screenshot of the pptx, where I am trying to add the two plots
Plot 1 (Age vs Name),
Plot 2 (Height vs Name),
but if you see the Plot 2 the data of plot 1 and plot 2 are getting overlapped. I want to avoid this overlapping.
You need to clear the axes between each plot, there are several ways to do that:
plt.clf(): clears the current figure
plt.cla(): clears the current axes
So instead of e.g.
plt.scatter(x, y1)
# save first plot
plt.scatter(x, y2)
# save second plot
You do
plt.scatter(x, y1)
# save first plot
plt.clf()
plt.scatter(x, y2)
# save second plot
And the two scatter plots will be drawn separately. This is probably the most 'blunt' way to approach this, but it should work fairly well. It is by no means the best way to do it for any specific case.
The figure is also cleared when plt.show() is called - but I expect that is undesirable in this case.
my problem is that I could only find answers for plots sharing the same y-axis units.
My graphs are defined as follows:
#Plot1
sns.set_style("white")
sns.catplot(y="Reaction_cd_positive", x="Flux_cd_positive",
kind="bar",height=4, data=CDP,aspect=1.5)
#Plot2
sns.catplot(y="Reaction_cd_negative",x="Flux_cd_negative",
kind="bar",height=4, data=CDN, aspect=1.5)
Thank you in advance!
Ok, let me translate this. You are using seaborn in a jupyter notebook. You want 2 barplots next to each other within the same figure, instead of two individual figures. Since catplot produces a figure by itself, there are two options.
Create a single catplot with two subplots. To this end you would need to concatenate your two DataFrames into a single one, then use the col argument to split the data into the two subplots.
Create a subplot grid with matplotlib first, then plot a barplot into each of the subplots. This is shown in this question.
What I'm looking to do is have a pair of 3D figures side by side.
In matplotlib, I was able to create these subplots like so:
ax1 = fig.add_subplot(121, projection='3d')
I'm trying to use Mayavi for my 3D plotting here, because it solves some other problems I'm having, but I can't seem to find a way to plot two figures side-by-side.
Is this even possible?
Every mayavi actor has position/origin/orientation attributes, which you can set to move them to different parts of the scene. You can also add multiple axes and tailor both the ranges over which they display and the labels output. Using a combination of these, you can solve your question; but no, I don't know of a simple "subplot" mechanism.
Other possible alternatives
mlab.screenshot() on separate scenes and combine them in a custom view.
use the canvas frontend inside your own screen widgets, with each side-by-side widget showing a different scene.
I need to return both a histogram and a scatterplot in one function using matplotlib, but when I try to create the histogram after creating the scatterplot, it appears that the scatterplot gets overridden. Just wondering if anyone has any advice on this issue? Is there a way to return two plots at once if they share an x-axis?
For instance, there is paragraph included in this link http://matplotlib.org/users/pyplot_tutorial.html about how to have 2 subplots. But I'm not sure how to do that with plt.hist() and plt.plot().
Since the histogram fills the bars it is probably better to do it first then the scatter plot.