简体   繁体   中英

matplotlib: subplots of same size?

I am having trouble with matplotlib in Python trying to create two plots side by side. I managed to make them stay next to each other, but I need them to have the exact same size: each point in the right one should be easily mapped to a location on the left one with the naked eye. Instead, my right one (which is a scatter plot) has some margins that make it appear slightly smaller than the left (a heatmap).

在此处输入图片说明

The way I generate the heatmap is:

def plot_map(matrix):
    # Plot it out
    #fig, ax = plt.subplots()
    fig = plt.figure()
    ax = plt.subplot(1,2,1)
    c = m.colors.ColorConverter().to_rgb
    cm = make_colormap([(0,1,0), (1,1,0), 0.1, (1,1,0), (1,0.5,0), 0.66, (1,0.5,0),(1,0,0)]) 
    heatmap = ax.pcolor(matrix, cmap=cm)

    # Format
    fig = plt.gcf()
    fig.set_size_inches(20, 20)
    plt.gca().set_aspect('equal')
    # turn off the frame
    ax.set_frame_on(False)

    # put the major ticks at the middle of each cell
    ax.set_yticks(np.arange(matrix.shape[0]) + 0.5, minor=False)
    ax.set_xticks(np.arange(matrix.shape[1]) + 0.5, minor=False)

    # want a more natural, table-like display
    ax.invert_yaxis()
    ax.xaxis.tick_top()

    # note I could have used matrix.columns but made "labels" instead
    ax.set_xticklabels(range(0,matrix.shape[0]), minor=False)
    ax.set_yticklabels(range(0,matrix.shape[1]), minor=False)
    ax.grid(False)

    # Turn off all the ticks
    ax = plt.gca()

    for t in ax.xaxis.get_major_ticks():
        t.tick1On = False
        t.tick2On = False
    for t in ax.yaxis.get_major_ticks():
        t.tick1On = False
        t.tick2On = False

    divider = make_axes_locatable(ax)       
    cax = divider.append_axes("right", size="5%", pad=0.05)
    plt.colorbar(heatmap,cax=cax)

    return (fig,ax)

Then the ax is passed over to another function to plot the little blue lines on the map:

def plot_chosen(edges,endnodes,side,ax):
    for e in edges:
        u = endnodes[e - 1][0]
        v = endnodes[e - 1][1]
        xu, yu = get_center(u,side)
        xv, yv = get_center(v,side)
        ax.plot([xu+0.5, xv+0.5], [yu+0.5, yv+0.5], 'k-', lw=4, color='blue',alpha=0.5)

Finally, I plot the scatter like this

def plot_satter(edges,endnodes,side,xs,ys,data):
    plt.margins(0)
    ax = plt.subplot(1, 2, 2)
        # Format
    fig = plt.gcf()
    fig.set_size_inches(20, 20)
    plt.gca().set_aspect('equal')
    # turn off the frame
    ax.set_frame_on(False)

    # put the major ticks at the middle of each cell
    ax.set_yticks(np.arange(side) + 0.5, minor=False)
    ax.set_xticks(np.arange(side) + 0.5, minor=False)

    # want a more natural, table-like display
    ax.invert_yaxis()
    ax.xaxis.tick_top()

    ax.set_xmargin(0)
    ax.set_ymargin(0)

    # note I could have used matrix.columns but made "labels" instead
    ax.set_xticklabels(range(0,side), minor=False)
    ax.set_yticklabels(range(0,side), minor=False)
    ax.grid(False)

    # Turn off all the ticks
    ax = plt.gca()

    for t in ax.xaxis.get_major_ticks():
        t.tick1On = False
        t.tick2On = False
    for t in ax.yaxis.get_major_ticks():
        t.tick1On = False
        t.tick2On = False
    cm = make_colormap([(0,0,1), (0,1,1), 0.1, (0,1,1), (1,1,0), 0.66, (1,1,0),(1,0,0)]) 
    resmap = plt.scatter(xs,ys, c=data,cmap=cm,edgecolors='none',alpha=0.5,s=data)
    divider = make_axes_locatable(ax)       
    cax = divider.append_axes("right", size="5%", pad=0.05)
    plt.colorbar(resmap,cax=cax)

But I find no way of making the scatter plot as big as the heatmap. Actually, it's supposed to be as big as its colorbar, but that doesn't work either... Si this makes me think there is some margin around the scatter....

Also, is there a way I could make the whole PNG file not so square? Could it be a rectangle?

Thanks!

In order to get help, you need to provide a minimal working example . You will find out that producing such a minimal working example , almost always makes you find the problem and a corresponding solution yourself.
Also, structure your code!!

As we do not have the necessary knowledge of your data and the variables you are using, it is almost impossible to come up with a solution.

What you need to do is break down the problem. You are looking for the difference between two things - so make them as equal as possible. If you apply everything to both plots simultaneously, how can they be different after all?

The following code shows how you would do that and it acutally shows no difference in size of the two plots. So start from there and add the stuff you might need accordingly. One step at a time, until you find the piece of code that causes problems.

import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.axes_grid1 import make_axes_locatable

x = np.linspace(0,100,101)
X, Y = np.meshgrid(x,x)
data = np.sin(X/2.3)*np.cos(Y/2.7)*np.cos(X*Y/20.)

fig = plt.figure(figsize=(10,5))
ax1=fig.add_subplot(121)
ax2=fig.add_subplot(122)
plt.subplots_adjust(wspace = 0.33 )

heatmap = ax1.pcolor(data, cmap="RdPu")
resmap =  ax2.scatter(X,Y, c=data, cmap="YlGnBu",edgecolors='none',alpha=0.5)


for ax in [ax1,ax2]:
    ax.set_frame_on(False)

    ax.set_aspect('equal')

    ax.invert_yaxis()
    ax.xaxis.tick_top()

    ax.set_xmargin(0)
    ax.set_ymargin(0)

    ax.grid(False)

    for t in ax.xaxis.get_major_ticks():
        t.tick1On = False
        t.tick2On = False
    for t in ax.yaxis.get_major_ticks():
        t.tick1On = False
        t.tick2On = False

    ax.set_xlim([x[0],x[-1]])
    ax.set_ylim([x[0],x[-1]])


divider1 = make_axes_locatable(ax1)       
cax1 = divider1.append_axes("right", size="5%", pad=0.05)
plt.colorbar(heatmap,cax=cax1)

divider2 = make_axes_locatable(ax2)       
cax2 = divider2.append_axes("right", size="5%", pad=0.05)
plt.colorbar(resmap,cax=cax2)

plt.show()

And btw, fig = plt.figure(figsize=(10,5)) produces a rectangle, while fig = plt.figure(figsize=(20,20)) produces a square.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM