490

How do I change the size of my image so it's suitable for printing?

For example, I'd like to use to A4 paper, whose dimensions are 11.7 inches by 8.27 inches in landscape orientation.

Trenton McKinney
  • 56,955
  • 33
  • 144
  • 158
Michael Grazebrook
  • 5,361
  • 3
  • 16
  • 18

13 Answers13

537

You can also set figure size by passing dictionary to rc parameter with key 'figure.figsize' in seaborn set method:

import seaborn as sns

sns.set(rc={'figure.figsize':(11.7,8.27)})

Other alternative may be to use figure.figsize of rcParams to set figure size as below:

from matplotlib import rcParams

# figure size in inches
rcParams['figure.figsize'] = 11.7,8.27

More details can be found in matplotlib documentation

niraj
  • 17,498
  • 4
  • 33
  • 48
  • 9
    Unlike other solutions, this solution doesn't assume a certain way of defining the plot. Thanks. – LoMaPh Sep 09 '18 at 03:02
  • 31
    Note that when you call sns.set(), it defaults your figure styles to the sns default instead of the matplotlib default, for example your figures would then suddenly have a grey background with white grid – see here: https://seaborn.pydata.org/tutorial/aesthetics.html. Also, this didn't have any effect on the size of my plot (a sns.pairplot). – Melissa Oct 24 '18 at 08:00
  • 3
    Nor mine as a sns.boxplot – Gordon Aug 15 '19 at 10:10
  • Thanks for that @Melissa. This made me realise I have to call `.set()` before `.set_style()` – gosuto Apr 16 '20 at 13:01
  • 4
    Alas they both don't produce any plot in Jupyter Lab. `fig, ax = pyplot.subplots(figsize=(20, 2)); a = sns.lineplot(ax=ax, x=..., y=...)` instead works as expected. I am always surprised when such parameters, that should be straightforward in seaborn because used very often, need to be set using "tricks". – Alex Poca Jul 13 '20 at 08:58
  • Note that `sns.set()` (and `sns.set_style()`) have to precede the plot (and `sns.set_style()` has to precede `plt.subplots()`, if you go for this alternative). – Skippy le Grand Gourou Jul 06 '21 at 14:16
  • 1
    Don't know how many times have I visited this question just to copy paste the line hahah. Mi figures are all (11.7,8.27) – Juan Luis Ruiz-tagle Jul 10 '22 at 20:11
324

You need to create the matplotlib Figure and Axes objects ahead of time, specifying how big the figure is:

from matplotlib import pyplot
import seaborn

import mylib

a4_dims = (11.7, 8.27)
df = mylib.load_data()
fig, ax = pyplot.subplots(figsize=a4_dims)
seaborn.violinplot(ax=ax, data=df, **violin_options)
Paul H
  • 65,268
  • 20
  • 159
  • 136
  • 11
    this solution does not seem to work with the code that follows (different kind of plot). Any ideas? I assume "mylib" is just a library where you stored your data and is not needed in this code: ` fig, ax = pyplot.subplots(figsize=(12,6)); sns.jointplot(memoryPrice['price'], memoryPrice['Memory']) ` – TMWP Aug 01 '17 at 03:25
  • 3
    This answer doesn't work in @TMWP's case because jointplot is a figure level method. See answer below. – elz Aug 01 '18 at 14:04
  • 9
    this answer doesn't work with those plot types that don't accept ax as an input, for example `sns.lmplot()` – F.S. Sep 25 '18 at 00:28
  • 5
    Plot size in seaborn should be set using the `height` and `aspect` parameters as explained here https://stackoverflow.com/a/51602446/2412831 – LeandroOrdonez Sep 10 '19 at 12:38
  • @LeandroOrdonez that's not really applicable to axes-level function. – Paul H Sep 10 '19 at 15:03
255

Note that if you are trying to pass to a "figure level" method in seaborn (for example lmplot, catplot / factorplot, jointplot) you can and should specify this within the arguments using height and aspect.

sns.catplot(data=df, x='xvar', y='yvar', 
    hue='hue_bar', height=8.27, aspect=11.7/8.27)

See https://github.com/mwaskom/seaborn/issues/488 and Plotting with seaborn using the matplotlib object-oriented interface for more details on the fact that figure level methods do not obey axes specifications.

elz
  • 5,338
  • 3
  • 28
  • 30
  • 52
    This is the only answer so far that correctly deals with sns plots that don't accept ax as an argument. – Melissa Oct 24 '18 at 07:56
  • 6
    Note that height and aspect control the dimensions of a single "facet," i.e. a subplot. So this doesn't directly adjust the full figure dimensions. – bernie Jan 22 '20 at 03:39
  • 4
    See also [this official tutorial](https://seaborn.pydata.org/tutorial/function_overview.html#specifying-figure-sizes) – JohanC Dec 22 '20 at 21:10
  • 1
    Note: this applies to `relplot` too. Even when creating a figure ahead of time using `plt.figure(figsize=...)`, I still needed to specify `height`/`aspect` to get the dimensions to change. I prefer this much more than the `sns.set()` solution because I want different values for different plots. – Neil Traft Nov 10 '22 at 14:33
151

first import matplotlib and use it to set the size of the figure

from matplotlib import pyplot as plt
import seaborn as sns

plt.figure(figsize=(15,8))
ax = sns.barplot(x="Word", y="Frequency", data=boxdata)
Shubham Chaudhary
  • 47,722
  • 9
  • 78
  • 80
Gucci148
  • 1,977
  • 1
  • 13
  • 4
108

You can set the context to be poster or manually set fig_size.

import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt

np.random.seed(0)
n, p = 40, 8
d = np.random.normal(0, 2, (n, p))
d += np.log(np.arange(1, p + 1)) * -5 + 10


# plot
sns.set_style('ticks')
fig, ax = plt.subplots()
# the size of A4 paper
fig.set_size_inches(11.7, 8.27)
sns.violinplot(data=d, inner="points", ax=ax)    
sns.despine()

fig.savefig('example.png')

enter image description here

Jianxun Li
  • 24,004
  • 10
  • 58
  • 76
  • 5
    this answer doesn't work with those plot types that don't accept ax as an input, for example `sns.lmplot()` – F.S. Sep 25 '18 at 00:29
  • 1
    To expand on Chris's answer, some seaborn plots generate composite figures with multiple axes, so they CAN'T take a single axis as an argument. – Marmaduke Nov 13 '18 at 16:43
  • This worked for me when trying to plot a violinplot. I was able to change the size of the figure inline in a Jupiter lab notebook. – muammar Jul 15 '20 at 18:51
67

This can be done using:

plt.figure(figsize=(15,8))
sns.kdeplot(data,shade=True)
PSN
  • 2,326
  • 3
  • 27
  • 52
63

In addition to elz answer regarding "figure level" methods that return multi-plot grid objects it is possible to set the figure height and width explicitly (that is without using aspect ratio) using the following approach:

import seaborn as sns 

g = sns.catplot(data=df, x='xvar', y='yvar', hue='hue_bar')
g.fig.set_figwidth(8.27)
g.fig.set_figheight(11.7)
Nick Lothian
  • 1,427
  • 1
  • 15
  • 31
dmainz
  • 985
  • 7
  • 6
  • 1
    `set_figwidth` and `set_figheight` work well for grid objects. >>> import seaborn >>> import matplotlib.pyplot as pyplot >>> tips = seaborn.load_dataset("tips") >>> g = seaborn.FacetGrid(tips, col="time", row="smoker") >>> g = g.map(pyplot.hist, "total_bill") >>> g.fig.set_figwidth(10) >>> g.fig.set_figheight(10) – Paul Rougieux Dec 02 '19 at 16:30
  • 3
    Perhaps the API changed, but for me it was g.figure.set_figwidth instead of g.fig.set_figwidth. I'm using matplotlib version 3.1.0 and seaborn 0.9.0 – NateW Jan 23 '20 at 19:54
  • works with seaborn version `0.11.1` - the other solutions on this page didn't work – joshi123 Feb 23 '21 at 13:51
  • 1
    Thank you so much, this is the only solution that has worked for me. Been trying to figure this out for like 15 minutes now – Nick May 19 '21 at 02:50
  • 1
    15 minutes? Try 15 hours – Jesse Kerr Jul 28 '22 at 18:31
30

This shall also work.

from matplotlib import pyplot as plt
import seaborn as sns    

plt.figure(figsize=(15,16))
sns.countplot(data=yourdata, ...)
Mufaddal Tahir
  • 509
  • 4
  • 9
28

For my plot (a sns factorplot) the proposed answer didn't works fine.

Thus I use

plt.gcf().set_size_inches(11.7, 8.27)

Just after the plot with seaborn (so no need to pass an ax to seaborn or to change the rc settings).

head7
  • 1,373
  • 12
  • 12
  • 1
    This is the only solution that works for me with a FacetGrid ```python g = sns.FacetGrid(df.set_index('category'), col="id") pyplot.gcf().set_size_inches(11.7, 8.27) g.map(lambda data, color: data.plot.barh(color=color), "count") ``` – Nicolas78 Aug 16 '19 at 08:26
  • Same here. It seems like `sns.FacetGrid` would set a figure size according to a calculated value (set by `height` and `aspect`) and changing the figure size directly after seaborn plotting will work. And other fine tuning of the plot can happen after changing the figure size – Yunting Zhao Dec 12 '19 at 22:47
24

Imports and Data

import seaborn as sns
import matplotlib.pyplot as plt

# load data
df = sns.load_dataset('penguins')

sns.displot

  • The size of a figure-level plot can be adjusted with the height and/or aspect parameters
  • Additionally, the dpi of the figure can be set by accessing the fig object and using .set_dpi()
p = sns.displot(data=df, x='flipper_length_mm', stat='density', height=4, aspect=1.5)
p.fig.set_dpi(100)
  • Without p.fig.set_dpi(100)

enter image description here

  • With p.fig.set_dpi(100)

enter image description here

sns.histplot

  • The size of an axes-level plot can be adjusted with figsize and/or dpi
# create figure and axes
fig, ax = plt.subplots(figsize=(6, 5), dpi=100)

# plot to the existing fig, by using ax=ax
p = sns.histplot(data=df, x='flipper_length_mm', stat='density', ax=ax)
  • Without dpi=100

enter image description here

  • With dpi=100

enter image description here

Trenton McKinney
  • 56,955
  • 33
  • 144
  • 158
15
# Sets the figure size temporarily but has to be set again the next plot
plt.figure(figsize=(18,18))

sns.barplot(x=housing.ocean_proximity, y=housing.median_house_value)
plt.show()

An 18x18 plot of my graph

Jerrold110
  • 191
  • 1
  • 4
  • `plt.figure(figsize=(X,Y))` does nothing, at least with the Jupyter extension in VS Code and seaborn 0.12.2 – sharchaea Jun 06 '23 at 03:19
10

Some tried out ways:

import seaborn as sns
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=[15,7])
sns.boxplot(x="feature1", y="feature2",data=df, ax=ax) # where df would be your dataframe

or

import seaborn as sns
import matplotlib.pyplot as plt
plt.figure(figsize=[15,7])
sns.boxplot(x="feature1", y="feature2",data=df) # where df would be your dataframe
Corralien
  • 109,409
  • 8
  • 28
  • 52
rmswrp
  • 501
  • 5
  • 5
9

The top answers by Paul H and J. Li do not work for all types of seaborn figures. For the FacetGrid type (for instance sns.lmplot()), use the size and aspect parameter.

Size changes both the height and width, maintaining the aspect ratio.

Aspect only changes the width, keeping the height constant.

You can always get your desired size by playing with these two parameters.

Credit: https://stackoverflow.com/a/28765059/3901029

F.S.
  • 1,175
  • 2
  • 14
  • 34