Samufi
Samufi

Reputation: 2710

Matplotlib: let color bar not affect size and proportions of the plot

I want to create a plot in matplotlib with a specified size, say

plt.figure(figsize=(3, 3))

I add some content to the figure and draw a color bar

plt.colorbar()

Now the original size of the whole figure (3x3 inches) is maintained, but the width of the plot (the actual content) is reduced to fit both the plot and the color bar in the 3x3 inch window.

Without color bar With color bar

How can I keep the width of the plotting area fixed and adjust the size of the whole figure as required when I add a color bar?

Upvotes: 6

Views: 7442

Answers (2)

Samufi
Samufi

Reputation: 2710

Based on BenT's answer, I could come up with a solution that also adjusts the figure size.

First, I define a method that returns the two axes that will later be used for the original figure and the color bar:

def split_figure_vertically(figsize_1, additional_width, rect_1, rect_2):
    """
    figsize_1 is the size of the figure without the color bar
    additional_width is the additional width used for the color bar
    rect_1, rect_2 define where the plotting area and color bar are located
    in their respective sections of the figure
    """
    oldWidth_1 = figsize_1[0]
    newWidth = oldWidth_1 + additional_width
    factor_1 = oldWidth_1 / newWidth
    factor_2 = additional_width / newWidth
    
    figsize = (newWidth, figsize_1[1])
    
    fig = plt.figure(figsize=figsize)
    
    rect_1[0] *= factor_1
    rect_1[2] *= factor_1
    
    rect_2[0] *= factor_2
    rect_2[2] *= factor_2
    rect_2[0] += factor_1
    
    ax1 = fig.add_axes(rect_1)
    ax2 = fig.add_axes(rect_2)
    
    return ax1, ax2

I call the function returning the different axes when I want to plot the color bar:

figsize = (3, 3)
rect = [0.2, 0.2, 0.7, 0.7]

if colorBar:
    ax1, ax2 = split_figure_vertically(figsize, 1, rect, 
                                       [0., 0.2, 0.2, 0.7])
else:
    ax1 = plt.figure(figsize=figsize).add_axes(rect)

Then I plot my content on axis 1 as usual and plot the color bar on axis 2 as suggested by BenT.

if colorBar:
    plt.colorbar(cax=ax2)

The result is as desired.

Without color bar With color bar

Upvotes: 2

BenT
BenT

Reputation: 3200

You need to create a separate figure axis and then add the colorbar to that axis. Then when you change the figure size the colorbar will not eat into your figure dimensions. See this answer.

Something like this:

import numpy as np
from matplotlib import pyplot as plt

x = np.arange(-10,11,1)
y=x
x,y = np.meshgrid(x,y)
Z = x**2-y**2

fig = plt.figure(figsize=(3,3))

im = plt.contourf(x,y,Z)

cb_ax = fig.add_axes([.91,.124,.04,.754])
fig.colorbar(im,orientation='vertical',cax=cb_ax)


plt.show()

enter image description here

Upvotes: 6

Related Questions