How to change the figure size of a seaborn axes or figure level plot
Asked Answered
O

14

503

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

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

Orcus answered 23/7, 2015 at 17:43 Comment(0)
R
333

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)
Raid answered 23/7, 2015 at 20:19 Comment(5)
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']) `Numbersnumbfish
This answer doesn't work in @TMWP's case because jointplot is a figure level method. See answer below.Argile
this answer doesn't work with those plot types that don't accept ax as an input, for example sns.lmplot()Moriarty
Plot size in seaborn should be set using the height and aspect parameters as explained here https://mcmap.net/q/73969/-how-to-change-the-figure-size-of-a-seaborn-axes-or-figure-level-plotAlfaro
@Alfaro that's not really applicable to axes-level function.Raid
D
552

You can also set figure size by passing dictionary to rc parameter with key 'figure.figsize' in seaborn set_theme method (which replaces the set method, deprecated in v0.11.0 (September 2020))

import seaborn as sns

sns.set_theme(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

Denaturalize answered 23/12, 2017 at 20:34 Comment(7)
Unlike other solutions, this solution doesn't assume a certain way of defining the plot. Thanks.Mahaliamahan
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: seaborn.pydata.org/tutorial/aesthetics.html. Also, this didn't have any effect on the size of my plot (a sns.pairplot).Crape
Nor mine as a sns.boxplotTantamount
Thanks for that @Melissa. This made me realise I have to call .set() before .set_style()Augmenter
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".Prehistory
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).Crackpot
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)Scutage
R
333

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)
Raid answered 23/7, 2015 at 20:19 Comment(5)
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']) `Numbersnumbfish
This answer doesn't work in @TMWP's case because jointplot is a figure level method. See answer below.Argile
this answer doesn't work with those plot types that don't accept ax as an input, for example sns.lmplot()Moriarty
Plot size in seaborn should be set using the height and aspect parameters as explained here https://mcmap.net/q/73969/-how-to-change-the-figure-size-of-a-seaborn-axes-or-figure-level-plotAlfaro
@Alfaro that's not really applicable to axes-level function.Raid
A
271

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.

Argile answered 30/7, 2018 at 21:20 Comment(4)
This is the only answer so far that correctly deals with sns plots that don't accept ax as an argument.Crape
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.Colene
See also this official tutorialAutocephalous
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.Biblio
R
159

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)
Rightful answered 3/6, 2018 at 21:18 Comment(0)
H
110

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

Hyperphysical answered 23/7, 2015 at 20:13 Comment(3)
this answer doesn't work with those plot types that don't accept ax as an input, for example sns.lmplot()Moriarty
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.Phlyctena
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.Stria
K
69

This can be done using:

plt.figure(figsize=(15,8))
sns.kdeplot(data,shade=True)
Kif answered 15/8, 2019 at 18:57 Comment(0)
A
64

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)
Aureole answered 10/7, 2019 at 12:18 Comment(3)
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)Mariomariology
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.0Nicol
works with seaborn version 0.11.1 - the other solutions on this page didn't workShowthrough
D
32

This shall also work.

from matplotlib import pyplot as plt
import seaborn as sns    

plt.figure(figsize=(15,16))
sns.countplot(data=yourdata, ...)
Dorice answered 17/3, 2019 at 15:13 Comment(0)
F
29

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).

Foodstuff answered 11/12, 2018 at 14:3 Comment(2)
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") Quicken
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 sizeBronson
C
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

Charismatic answered 21/11, 2021 at 20:30 Comment(0)
U
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

Unblushing answered 23/4, 2021 at 8:3 Comment(1)
plt.figure(figsize=(X,Y)) does nothing, at least with the Jupyter extension in VS Code and seaborn 0.12.2Petulah
Y
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
Yorker answered 16/5, 2021 at 10:58 Comment(0)
M
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://mcmap.net/q/47213/-how-to-change-figuresize-using-seaborn-factorplot

Moriarty answered 25/9, 2018 at 0:42 Comment(0)
D
0

Change Axes-level plot size

Seaborn has plotter functions that return Axes objects. The size of those plots can be changed globally using the set() or set_theme() functions (as given in niraj's answer).

import seaborn as sns
df = sns.load_dataset("tips")

sns.set_theme(rc={'figure.figsize': (8.27, 11.7)})
ax = sns.regplot(df, x='total_bill', y='tip')

The size of these plots can also be changed by changing the size of the underlying matplotlib figure that contains this Axes using set_size_inches(). Note that dmainz's answer's answer does a similar thing but it works by setting the width and height separately; this method sets them both in one function call. This is especially useful if your seaborn plot is created somewhere else and you want to change its size to whatever you want in inches.

ax = sns.regplot(df, x='total_bill', y='tip')     # the default figsize is 6.4"x4.8"
ax.figure.set_size_inches(8.27, 11.7)             # now it becomes 8.27"x11.7"

If your seaborn plot is generated by the function that doesn't return a value, then you can still change it by accessing the current figure object using plt.gcf(). For example:

import matplotlib.pyplot as plt

sns.regplot(df, x='total_bill', y='tip')
plt.gcf().set_size_inches(8.27, 11.7)

Note that set() or set_theme() changes the figure size globally which may not be desirable if you only want to set a specific size of a single figure and use the default settings for others. In that case, you can use a context manager to change the figsize of a single figure.

with plt.rc_context(rc={'figure.figsize': (8.27, 11.7)}):
    sns.regplot(df, x='total_bill', y='tip')

Change figure / FacetGrid size

Similar to above where the underlying matplotlib figure size was changed, the same can be done for FacetGrid objects as well. A demo goes as follows:

g = sns.lmplot(data=df, x='total_bill', y='tip')  # the default figsize is 5"x5"
g.fig.set_size_inches(8.27, 11.7)                 # now it becomes 8.27"x11.7"

Note that if your seaborn figure is generated by the function that doesn't return a value, then you can still change it by accessing the current figure object using plt.gcf():

sns.lmplot(data=df, x='total_bill', y='tip')
plt.gcf().set_size_inches(8.27, 11.7)
Denitadenitrate answered 11/11, 2023 at 0:29 Comment(2)
The proposed method seems to be the same as https://mcmap.net/q/73969/-how-to-change-the-figure-size-of-a-seaborn-axes-or-figure-level-plot and https://mcmap.net/q/73969/-how-to-change-the-figure-size-of-a-seaborn-axes-or-figure-level-plotCharismatic
@TrentonMcKinney fair enough, especially the first one seems to use this method the way I intended to use here. I probably should remove the part in my answer that has the same code (or at least add link to that answer). Tbf, I hadn’t seen these answers before I posted mine (that’s my fault) but I still feel my answer better explains the different ways it could be useful. Also, I show different ways to access the figure in order to set its size (as well as the context manager) which could be useful in this context.Denitadenitrate

© 2022 - 2024 — McMap. All rights reserved.