【问题标题】:Adding legend in geopandas plot with subplots changes size of plot在带有子图的 geopandas 图中添加图例会改变图的大小
【发布时间】:2020-09-29 22:25:06
【问题描述】:

我想用 matplotlib 子图绘制两个 GeoPandas 图。两张地图有相同的图例,因此我只想有一个图例。但是,如果我在其中一个 GeoPandas 图中添加图例,则该图会稍微变小。这是一个问题,因为这两个地块的大小不同。

这是我的代码:

fig,ax = plt.subplots(1, 2, figsize=(12,8))
sealand_grid.plot(column=sealand_grid['p_2012'], 
                  ax=ax[0],
                  cmap='magma')
sealand_grid.plot(column=sealand_grid['p_2013'], 
                  ax=ax[1],
                  cmap='magma', 
                  legend=True,
                  legend_kwds={'shrink': 0.3})
ax[0].set_title('Housing prices 2012', fontsize=18)
ax[1].set_title('Housing prices 2013', fontsize=18)
fig.patch.set_facecolor('xkcd:white')
ax[0].axis('off')
ax[1].axis('off')
fig.tight_layout()

sealand_grid 是我的 GeoPandas 数据框,p_2012 和 p_2013 是绘制在两张地图中的变量。

如何让两张地图大小相同,而只有一个图例?

【问题讨论】:

    标签: python python-3.x matplotlib legend geopandas


    【解决方案1】:

    为了重现你的问题,我使用了这段代码,它基本上显示了相同的结果:由于颜色条,右侧的图像比左侧的图像略小。

    import matplotlib.pyplot as plt
    import numpy as np
    
    D2012 = np.random.rand(10, 10)
    D2013 = np.random.rand(10, 10)
    
    fig, (ax1, ax2) = plt.subplots(1, 2, figsize = (16,8))
    
    P2012 = ax1.imshow(D2012,
                 cmap = 'magma')
    P2013 = ax2.imshow(D2013,
                 cmap = 'magma')
    
    ax1.set_title('2012', fontsize = 18)
    ax2.set_title('2013', fontsize = 18)
    ax1.axis('off')
    ax2.axis('off')
    plt.colorbar(P2013)
    
    plt.show()
    

    这给出了这个情节:

    我解决了这个转变:

    import matplotlib.pyplot as plt
    import numpy as np
    
    D2012 = np.random.rand(10, 10)
    D2013 = np.random.rand(10, 10)
    
    fig, (ax1, ax2) = plt.subplots(1, 2, figsize = (16,8))
    ax3 = fig.add_axes([0.85, 0.1, 0.1, 0.8])
    
    P2012 = ax1.imshow(D2012,
                 cmap = 'magma')
    P2013 = ax2.imshow(D2013,
                 cmap = 'magma')
    
    ax1.set_title('2012', fontsize = 18)
    ax2.set_title('2013', fontsize = 18)
    ax1.axis('off')
    ax2.axis('off')
    ax3.axis('off')
    plt.colorbar(P2013, ax = ax3)
    
    plt.show()
    

    这给出了这个情节:

    基本上,我添加了第三个轴,将其关闭并添加颜色条。方法里面的参数需要注意这个第三轴的位置:fig.add_axes([0.85, 0.1, 0.1, 0.8]).
    我知道这肯定不是最优雅的解决方案。


    编辑

    更健壮和优雅的解决方案是保留 2 个轴,但在定义它们时设置它们的大小和位置:

    import matplotlib.pyplot as plt
    import numpy as np
    
    D2012 = np.random.rand(10, 10)
    D2013 = np.random.rand(10, 10)
    
    fig = plt.figure(figsize = (16,8))
    ax1 = fig.add_axes([0, 0.2, 0.6, 0.6])
    ax2 = fig.add_axes([0.4, 0.2, 0.6, 0.6])
    
    P2012 = ax1.imshow(D2012,
                 cmap = 'magma')
    P2013 = ax2.imshow(D2013,
                 cmap = 'magma')
    
    ax1.set_title('2012', fontsize = 18)
    ax2.set_title('2013', fontsize = 18)
    ax1.axis('off')
    ax2.axis('off')
    plt.colorbar(P2013)
    
    plt.show()
    

    这给出了这个情节:

    在这种情况下,你必须用这些线注意两个轴的位置和大小:

    ax1 = fig.add_axes([0, 0.2, 0.6, 0.6])
    ax2 = fig.add_axes([0.4, 0.2, 0.6, 0.6])
    

    【讨论】:

    • 谢谢!您的第一个建议不能解决问题,因为我是从 geopandas 图中添加颜色条,而不是从 matplotlib 包中添加。但是,在初始化子图时指定坐标轴大小的 EDIT 可以解决问题。
    【解决方案2】:

    一种方法是创建一个专用轴来绘制颜色条。因此为 2 个所需的图创建了 3 个轴。注意使用gridspec_kw 和width_ratios 的正确值来获得所需的子图宽度。这是可运行的代码和结果图。

    import numpy as np
    import matplotlib.pyplot as plt
    
    # create simple data for demo plot
    data = np.arange(100, 0, -1).reshape(10, 10)
    
    # figsize plays important role; must set it wide enough
    # here 3 axes are created
    # the width ratio of the 3rd axes must be small to get good result (here = 0.03)
    fig, ax = plt.subplots(1, 3, figsize=(9.5, 4), gridspec_kw={"width_ratios":[0.4535, 0.4535, 0.03]})
    
    # first 2 axes are used to plot images
    im0 = ax[0].imshow(data, cmap='bone')
    im1 = ax[1].imshow(data, cmap='bone')
    
    # The third axes, ax[2] is exclusive to the color bar
    # When cax id specified, 'shrink' and 'aspect' properties are ignored
    cb = fig.colorbar(im0, cax=ax[2], orientation='vertical')
    
    plt.show()
    

    使用这种方法,颜色条可以放置在 3 个轴中的任何一个上,但您必须相应地更改代码才能完成。

    【讨论】:

    • @Andrea Blengino 你怎么能说他们是一样的。结果?不,方法是代码而不是结果。我正在考虑投票给你。现在我必须等一会儿。你的回答很好,没有理由不这样做。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-10-07
    • 1970-01-01
    • 2022-08-19
    • 2015-08-15
    • 1970-01-01
    • 2019-06-11
    • 1970-01-01
    相关资源
    最近更新 更多