Matplotlib figsize not respected [duplicate] - python

This question already has answers here:
Matplotlib and Ipython-notebook: Displaying exactly the figure that will be saved
(2 answers)
Closed 4 years ago.
I want to make a square plot with matplotlib. That is, I want the whole figure to be square. When I use the following code, the width of the resulting image is still a bit larger than the height. Why is matplotlib not respecting the figsize I provide?
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(10, 10))
# When inspecting in browser, reveals 611x580 px image
ax.plot([1,2,3], [1,2,3])
Edit: I display the image inline in a Jupyter notebook, and just use the Chrome developer tools to inspect the image.

That is a problem of jupyter notebook. The figure it shows is a "saved" version, which uses the bbox_inches="tight" option and hence changes the size of the shown image.
One option you have is to save the figure manually to png,
fig.savefig("output.png")
As #EvgenyPogrebnyak commented, the other option is to deactivate the "tight" option in the notebook as
%matplotlib inline
%config InlineBackend.print_figure_kwargs = {'bbox_inches':None}
fig, ax = plt.subplots(figsize=(10, 10))
# When inspecting in browser,
ax.plot([1,2,3], [1,2,3]) # now reveals 720 x 720 px image
as seen in this answer.

Related

Jupyter: How do I prevent matplotlib figures from being automatically shown? [duplicate]

This question already has answers here:
prevent plot from showing in jupyter notebook
(7 answers)
How to prevent matplotlib from to showing a figure even with plt.close() in jupyter notebook
(1 answer)
Closed 9 months ago.
I like to only show a matplotlib figure with an explicit show(fig). But Jupyter automatically shows all created figures.
This link has a workaround, but it is essentially just capturing all the output of a cell. I don't want to do that.
Related:
https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.show.html#:~:text=auto-show%20in%20jupyter%20notebooks
PS: I am actually using seaborn, not matplotlib directly.
Using plt.ioff disables interactive mode and storing figure in a variable won't display any output:
import matplotlib.pyplot as plt
import numpy as np
import seaborn as sns
plt.ioff()
sns.set_theme(style="darkgrid")
# Load an example dataset with long-form data
fmri = sns.load_dataset("fmri")
# Plot the responses for different events and regions
fig = sns.lineplot(x="timepoint", y="signal",
hue="region", style="event",
data=fmri)
But using plt.show() reverses the effect and show the output figure:
# Import modules here
plt.ioff()
# Set theme and load data here
fig = sns.lineplot(x="timepoint", y="signal",
hue="region", style="event",
data=fmri)
plt.show()
How the Jupyter Notebook output looks like when the above code is used:
The code for plotting the Timeseries plot comes from here.

How to show specific axes in a figure

I created a figure which has 2 axes, how can I plot specific axes(eg,ax[0]) rather than plot both axes? When I input fig in the end both axes will appear together. What code should I write if I just want ax[0] be displayed for example?
fig,ax=plt.subplots(2)
x=np.linspace(1,10,100)
ax[0].plot(x,np.sin(x))
ax[1].plot(x,np.cos(x))
fig
I interprete that you are using Jupyter notebook. You may then use the fact that invisble axes parts of a figure will be cropped with the matplotlib inline backend.
%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
fig,ax=plt.subplots(2);
x=np.linspace(1,10,100)
ax[0].plot(x,np.sin(x))
ax[1].plot(x,np.cos(x))
Now to only show the second subplot, you can set the first invisible,
ax[0].set_visible(False)
fig
If you then want to only show the first subplot, you need to set it visible again and the second one invisible
ax[0].set_visible(True)
ax[1].set_visible(False)
fig

Matplotlib: savefig produces incorrect SVG image for bar chart with log-scaled Y-axis

I'm having an issue when trying to save a bar plot as an svg. Specifically, when I save the bar plot as a PDF with savefig, I get the correct result. However, when I save it as an SVG, the bars do not terminate at the x-axis as they should but descend past the bottom of the figure. This problem only occurs when I use the log scale for the bar plot. Otherwise, everything is hunky dory.
Here is the code saving the plot as both an SVG and a PDF:
import matplotlib.pyplot as plt
import numpy as np
N = 10
ind = np.arange(N)
series1 = xrange(N)
series2 = [ N - s1_i for s1_i in series1 ]
fig, ax = plt.subplots()
width = 0.2
rects = [ ax.bar(ind, series1, width, color='r', log=True),
ax.bar(ind + width, series2, width, color='b', log=True) ]
plt.savefig("test.pdf")
plt.savefig("test.svg")
Here are the two sample images:
You can see there are no glaring issues with the PDF version.
The SVG version has bars that are not properly clipped, which is wrong.
Update: In response to tcaswell
I'm using Ubuntu 14.04 (kernel version is 3.16.0) with Python 2.7.6, Matplotlib version 1.3.1, numpy version 1.8.2.
I've tried viewing the SVG both with display and rsvg-view-3, and both show the same result; if I convert it to a PDF using ImageMagick's convert command line tool and open it with evince or another viewer such as acroread, the image remains flawed (not particularly surprising).
This is a known bug in librsvg (and limitation in libQtSvg which only handles a very restricted sub-set of SVG (1.2 tiny) which does not include clipping at all).
The svg will render correctly in any modern browser.
There is a much longer discussion at https://github.com/matplotlib/matplotlib/issues/4341, but the long and short of it is that the renderer is buggy.

Blank image when saving an imshow matplotlib figure in iPython notebook

I'm using iPython notebook w/ matplotlib to display a bunch of images inline, but now it's come time to save a number of these images (think for-loop, i.e. not a small number of images to save). My issue seems to be something to do with how I'm using iPython since I could do this alright when my script was a standalone.
%matplotlib inline
import matplotlib.pyplot as plt
....
grid_z2 = griddata(....)
fig = plt.figure()
ax = fig.add_axes([1,1,1,1])
plt.imshow(grid_z2.transpose(),origin='Lower')
plt.colorbar()
plt.draw()
fig.savefig('slicemap.png')
I have also tried plt.savefig(), fig1 = plt.gcf() before plt.imshow then trying to save fig1... always every single time a blank file.
Any suggestions?

Change figure size and figure format in matplotlib [duplicate]

This question already has answers here:
How do I change the size of figures drawn with Matplotlib?
(14 answers)
Closed 1 year ago.
I want to obtain fig1 exactly of 4 by 3 inch sized, and in tiff format correcting the program below:
import matplotlib.pyplot as plt
list1 = [3,4,5,6,9,12]
list2 = [8,12,14,15,17,20]
plt.plot(list1, list2)
plt.savefig('fig1.png', dpi = 300)
plt.close()
You can set the figure size if you explicitly create the figure with
plt.figure(figsize=(3,4))
You need to set figure size before calling plt.plot()
To change the format of the saved figure just change the extension in the file name. However, I don't know if any of matplotlib backends support tiff
You can change the size of the plot by adding this before you create the figure.
plt.rcParams["figure.figsize"] = [16,9]
The first part (setting the output size explictly) isn't too hard:
import matplotlib.pyplot as plt
list1 = [3,4,5,6,9,12]
list2 = [8,12,14,15,17,20]
fig = plt.figure(figsize=(4,3))
ax = fig.add_subplot(111)
ax.plot(list1, list2)
fig.savefig('fig1.png', dpi = 300)
fig.close()
But after a quick google search on matplotlib + tiff, I'm not convinced that matplotlib can make tiff plots. There is some mention of the GDK backend being able to do it.
One option would be to convert the output with a tool like imagemagick's convert.
(Another option is to wait around here until a real matplotlib expert shows up and proves me wrong ;-)
If you need to change the figure size after you have created it, use the methods
fig = plt.figure()
fig.set_figheight(value_height)
fig.set_figwidth(value_width)
where value_height and value_width are in inches. For me this is the most practical way.

Categories

Resources