I have the following code that did not work:
import matplotlib.pyplot as plt
# Make the plot
fig, axs = plt.subplots(3, 1, figsize=(3.27, 6))
axs[0].plot(range(5), range(5), label='label 1')
axs[0].plot(range(5), range(4, -1, -1), label='label 2')
axs[0].legend(bbox_to_anchor=(0, 1.1, 1., 0.1), mode='expand', ncol=2, frameon=True, borderaxespad=0.)
# Adjust subplots to make room
fig.subplots_adjust(top=.5)
fig.savefig('test.png', format='png', dpi=300)
It can be seen that the fig.subplots_adjust did not work at all.
I am using WinPython 3.3.2.3 64 bit, with matplotlib version 1.3.0 and CPython 3.3. This happened in IPython Notebook. The backend is the in-line one. The output from the notebook is complete, but the output file is improperly cropped. In both notebook & saved file, the subplots_adjust command has no effect.
With the help of tcaswell, I got it solved by entirely closing the IPython Notebook and re-run the code via the ipython-qtconsole. It seems that the subplots_adjust() simply doesn't work for python 3 in ipython-notebook. I am new to python, and is really interested in what difference is there between the qtconsole and the notebook, backend-wise, if anyone has got ideas.
Anyways - good to have this problem solved!
Related
I am trying to create a 2x2 plots for Anscombe data-set
Loading Data-set and separating each class in data-set
import seaborn as sns
import matplotlib.pyplot as plt
anscombe = sns.load_dataset('anscombe')
dataset_1 = anscombe[anscombe['dataset'] == 'I']
dataset_2 = anscombe[anscombe['dataset'] == 'II']
dataset_3 = anscombe[anscombe['dataset'] == 'III']
dataset_4 = anscombe[anscombe['dataset'] == 'IV']
Creating a figure and dividing into 4 parts
fig = plt.figure()
axes_1 = fig.add_subplot(2,2,1)
axes_2 = fig.add_subplot(2,2,2)
axes_3 = fig.add_subplot(2,2,3)
axes_4 = fig.add_subplot(2,2,4)
axes_1.plot(dataset_1['x'], dataset_1['y'], 'o')
axes_2.plot(dataset_2['x'], dataset_2['y'], 'o')
axes_3.plot(dataset_3['x'], dataset_3['y'], 'o')
axes_4.plot(dataset_4['x'], dataset_4['y'], 'o')
axes_1.set_title('dataset_1')
axes_2.set_title('dataset_2')
axes_3.set_title('dataset_3')
axes_4.set_title('dataset_4')
fig.suptitle('Anscombe Data')
fig.tight_layout()
The only output which i'm getting at each plot is
[<matplotlib.lines.Line2D at 0x24592c94bc8>]
What am I doing wrong?
If you are working with a Jupyter Notebook then you can add the following line to the top cell where you call all your imports. The following command will render your graph
%matplotlib inline
Add%matplotlib inline or use matplotlib.pyplot.ion()
after you imported matplotlib.
From plotting docs:
Starting with IPython 5.0 and matplotlib 2.0 you can avoid the use of
IPython’s specific magic and use
matplotlib.pyplot.ion()/matplotlib.pyplot.ioff() which have the
advantages of working outside of IPython as well.
I've tried all of the above, eventually I've found out there is a conflict between matplotlib and a library called dtale. When I removed the import dtale command and restarted the kernel all was working prefectly good.
%matplot plt
Executing this after plt.show() displayed the plots for me.
Found this here: How do I make matplotlib work in AWS EMR Jupyter notebook?
I recently had to re-install my OS and decided to switch to Python3. With it came updates of my IDE PyCharm and presumably also an update of Matplotlib.
Running a script that worked perfectly fine before, now gives me ugly results with overlapping titles of my subplots.
This is an example code:
import numpy as np
import matplotlib.pyplot as plt
z = np.random.uniform(low=0, high=100, size=(20,4))
fig, axes = plt.subplots(2, 2, constrained_layout=True, sharey=True, sharex=True)
axes[-1, 0].set_xlabel('.\n', color=(0, 0, 0, 0))
axes[-1, 0].set_ylabel('.\n', color=(0, 0, 0, 0))
for s_plot, ax in enumerate(axes.flat):
ax.scatter(x=range(20), y=z[:,s_plot])
fig.suptitle("The Title\nSecond Line\n", fontsize=12)
plt.show()
This produces:
I tried setting constrained_layout to False and also experimented with subplots_adjust, but it does not change the layout of my plots.
I am currently using matplotlib 3.0.2. Was there a major change I have missed? I am puzzled about how to solve this.
Using matplotlib 3.0.2 the plot would look as follows
Using constrained_layout=True
Using constrained_layout=False
Both outcomes are expected. In the case of constrained_layout being used the title appears off-center, because there is more space to the left of the subplots being used by labels than on the right.
I also think this is a problem with pycharm. So for example when I run the code in this standard matplotlib script:
https://matplotlib.org/3.1.1/gallery/subplots_axes_and_figures/figure_title.html
I get this image where the title and suptitle overlap:
However the title and suptitle do not overlap when saved to png.
I have raised an issue with pycharm to hopefully get this resolved:
https://youtrack.jetbrains.com/issue/PY-42545
In the meantime I suggest splitting your editor screen to display the .png file which you can refresh using CTRL+ALT+Y every time you run the code.
Here is the code I was using with matplotlib 2.2.3, which correctly appended a padded axis on the right of my figure:
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import make_axes_locatable
fig = plt.figure(1, clear=True)
axis = plt.gca()
divider = make_axes_locatable(axis)
new_axis = divider.append_axes("right", size="5%", pad=0.05)
plt.show()
fig.savefig('test.png', pad_inches=0, bbox_inches='tight')
However, since I updated matplotlib to version 3.0.0, the snippet above does not append an axis any more, but replaces the current axis. The fig.axes output shows that both axes are present:
[<matplotlib.axes._subplots.AxesSubplot object at 0x000001FEC0A38E80>,
<matplotlib.axes._axes.Axes object at 0x000001FEBD3A12E8>]
but there is only the new one visible in the figure overlapping and having the full size of the original axis.
The same code works OK with matplotlib 2.2.3. So my question is whether there are any changes in the interface of the divider introduced in version 3.0.0 or is it a bug? The documentation is scarce, but does not talk about any changes in the interface.
Update:
After much trouble, I've found out that the plots are shown correctly on my machine as well in matplotlib 3.0.0, but not saved correctly. I have localized the problem to a savefig option bbox_inches='tight'. So saving the figure with
fig.savefig('test.png', pad_inches=0, bbox_inches='tight')
saves only the colorbar, while
fig.savefig('test.png', pad_inches=0)
produces the whole figure, but with large white pads. In matplotlib 2.2.3 both lines produce the full figure (with or without pads). My new question is then: Is bbox_inches broken for this kind of applications in matplotlib 3.0.0 and how do I achive a figure with no white pads?
I have updated the MWE above to reproduce the error.
When I call:
model = doKMeans(user3, 4)
and then
ax.scatter(model.cluster_centers_[:,1], model.cluster_centers_[:,0],
s=169, c='r', marker='x', alpha=0.8, linewidths=2)
and then:
showandtell("Weekday Calls Centroids")
my chart appears empty. Any ideas why this is happening?
I believe the issue there is as simple as adding
plt.show()
to the end of your code.
Alternatively, another common mistake that might be causing that is that you if you are working on a jupyter notebook you might have forgot to add the command:
%matplotlib inline
when you import your matplotlib library
Hope that helps!
I have a strange problem with matplotlib that I can not seem to figure out. When using the ipython notebook with the pylab flag, ipython notebook --pylab inline I have a line of code that looks like this that is used to generate a colorbar with matplotlib:
im = ax.imshow(df, vmin=vmin, vmax=vmax)
The code works correctly and I get a nice colorbar. When I run this code as a python file I get an error, NameError: name 'ax' is not defined. I understand that the ipython notebook --pylab inline automatically imports a bunch of stuff into the notebook, but I cannot figure out what I need to import to fix the problem. print type(ax) gives:
<class 'matplotlib.axes.AxesSubplot'>
Can anyone point out why my code works in ipython but not a plain python file? Thanks in advance.
I had the same problem.
Per this entry:
How to abbreviate xtick labels years to 2 digits in a matplotlib plot
try defining 'ax' by adding (before the line causing the error):
ax = plt.gca()
I'm not quite sure what you've done, because aX isn't defined by default as part of pylab.
Normally, ax refers to an axis object. There are a few ways you can get one:
matplotlib.pyplot.gca() # gca = get current axis
matplotlib.pyplot.subplot(2,1,1) # For creating multiple plots in one figure
fig.get_axes()[x] # Where fig is a Figure object