matplotlib:相同大小的子图?

时间:2016-10-20 03:17:05

标签: python matplotlib plot scatter-plot subplot

我在Python中使用matplotlib时遇到麻烦,试图并排创建两个图。我设法使它们彼此相邻,但我需要它们具有完全相同的尺寸:右边的每个点应该用肉眼很容易地映射到左边的位置。 相反,我的右边(散点图)有一些边距使它看起来比左边(热图)略小。

enter image description here

我生成热图的方式是:

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)

然后将斧头传递给另一个函数以绘制地图上的小蓝线:

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)

最后,我像这样绘制散点图

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)

但我发现无法使散点图与热图一样大。实际上,它应该和它的颜色条一样大,但是它也不起作用......这让我觉得散布周围有一些余量....

另外,有没有办法让整个PNG文件不那么方正?它可能是一个矩形吗?

谢谢!

1 个答案:

答案 0 :(得分:3)

为了获得帮助,您需要提供minimal working example。您会发现生成这样的minimal working example几乎总是会让您自己找到问题并找到相应的解决方案。
另外,构建你的代码!!

由于我们没有必要的数据知识和您正在使用的变量,因此几乎不可能提出解决方案。

您需要做的是解决问题。你正在寻找两件事之间的区别 - 所以让它们尽可能相等。如果你同时将所有东西都应用到两个图上,那么它们怎么会有所不同呢?

以下代码显示了如何做到这一点,它实际上显示两个图的大小没有差异。所以从那里开始并相应地添加你可能需要的东西。一步一步,直到找到导致问题的代码片段。

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

顺便说一句,fig = plt.figure(figsize=(10,5))生成一个矩形,而fig = plt.figure(figsize=(20,20))生成一个正方形。