【问题标题】:matplotlib ax to figure extent - remove whitespace, borders, everything for plot of geopandas mapmatplotlib ax to figure extent - 删除空格、边框、geopandas 地图的所有内容
【发布时间】:2019-08-04 02:45:11
【问题描述】:

我正在寻找使用 matplotlib 绘制无缝地图图像的解决方案。当前的代码运行良好且稳定,但是它在左侧和底部留下了一个空格。我想删除这个空格,不知道怎么做。

我的示例代码:

import geopandas
from seaborn import despine
from pandas import read_csv
import matplotlib.pyplot as plt

# read data and shapefile
geo_path = 'shapefiles/ne_10m_admin_0_countries.shp'
df = read_csv('UNpopEstimates2100.csv')
world = geopandas.read_file(geo_path)

# specifiy what is to be plotted
cm = 'Greys'
world['2015'] = df['2015']

# set plot environment
fig = plt.figure()
ax = fig.add_axes([0, 0, 1, 1])
ax.axis('off')
plt.subplots_adjust(left=0, right=1, bottom=0, top=1)

world.plot(ax=ax, column='2015', cmap=cm, scheme='quantiles')

plt.savefig('sample.png', bbox_inches='tight', tight_layout=True, pad_inches=0, frameon=None)

sample.png

smaple.png with marked whitespace I would like to remove

我在 Matplotlib's Tight Layout guidemachinelearningplus.comRemoving white padding from figure on Reddit 以及其他几个 stackoverflow 帖子上关注了教程,即

Matplotlib scatter plot - Remove white padding,

Matplotlib: Getting subplots to fill figure,

Matplotlib plots: removing axis, legends and white spaces,

Removing white space around a saved image in matplotlib

matplotlib plot to fill figure only with data points, no borders, labels, axes,

我错过了什么?


编辑 - 提供具有非真实数据的可重现版本,但问题保持不变 - 我如何摆脱情节周围的空白?

我是 Geopandas 的新手,所以我不知道如何重新创建地理数据框,但是,它有内置的数据集。

world = geopandas.read_file(geopandas.datasets.get_path('naturalearth_lowres'))
world['2015'] = np.random.uniform(low=1., high=100., size=(177,))

fig = plt.figure()
ax = fig.add_axes([0, 0, 1, 1])
ax.axis('off')
plt.subplots_adjust(left=0, right=1, bottom=0, top=1)

world.plot(ax=ax, column='2015', scheme='quantiles')

plt.savefig('sample.png')

【问题讨论】:

  • 到目前为止我可以添加的东西,因为我试过了: - ax.set_xlim() 和 ax.set_ylim() 调整图像的位置和范围,但留下完全相同的空白 - plt.margins (x=0, y=0) 在这种情况下不会产生任何影响 - fig.subplots_adjust(wspace=0) 和 fig.subplots_adjust(hspace=0) 删除多个子图之间的空白,但这是一个单独的子图,所以它没有帮助 - ax.axis('off') 和 ax.set_axis_off() 接缝具有完全相同的效果 - 在代码中或在绘图之前重复 plt.tight_layout() 没有显示任何改进
  • plt.savefig('sample.png') 的结果是什么?这与你的追求相差多远?
  • @ImportanceOfBeingErnest 它为所有四个边留下了一个均匀的空白,明显更宽。
  • 如果四个边都有空格,那就奇怪了。你能让代码可重现吗(见minimal reproducible example,可能不需要真实世界的数据?)?
  • @ImportanceOfBeingErnest 上面的编辑是否更适合您?感谢您的输入!注意:即使我使用以前的plt.savefig('sample.png', bbox_inches='tight', tight_layout=True, pad_inches=0, frameon=None) 也无济于事。

标签: python matplotlib plot removing-whitespace geopandas


【解决方案1】:

首先,使用不同的 geopandas 版本是有区别的。至少应该确保使用 geopandas 0.4 以使地图具有正确的纵横比。

下一个需要移除轴内部的填充。这可以使用ax.margins(0) 命令来完成。

现在这会在一个方向(在本例中为顶部和底部)产生一些空白。一种选择是将图形缩小到轴的范围。

import numpy as np
import matplotlib; print(matplotlib.__version__)
import matplotlib.pyplot as plt
import geopandas; print(geopandas.__version__)

world = geopandas.read_file(geopandas.datasets.get_path('naturalearth_lowres'))
world['2015'] = np.random.uniform(low=1., high=100., size=(177,))

fig = plt.figure()
ax = fig.add_axes([0, 0, 1, 1])
ax.axis('off')

world.plot(ax=ax, column='2015', scheme='quantiles')

ax.margins(0)
ax.apply_aspect()
bbox = ax.get_window_extent().inverse_transformed(fig.transFigure)
w,h = fig.get_size_inches()
fig.set_size_inches(w*bbox.width, h*bbox.height)

plt.savefig('sample.png')
plt.show()

这样做的好处是图形的物理尺寸确实适合轴;所以无论是显示在屏幕上还是保存为图像,结果都是一样的。

如果目标只是保存没有空格的图形,您可以使用savefigbbox_inches 参数并以英寸为单位提供轴的实际范围。

fig = plt.figure()
ax = fig.add_axes([0, 0, 1, 1])
ax.axis('off')

world.plot(ax=ax, column='2015', scheme='quantiles')

ax.margins(0)
ax.apply_aspect()
bbox = ax.get_window_extent().inverse_transformed(fig.dpi_scale_trans)

plt.savefig('sample.png', bbox_inches=bbox)

最后,以上可以自动化,使用bbox_inches='tight'。但是,要使'tight' 选项正常工作,需要确保轴周围没有刻度线和标签,否则会增加间距。

fig = plt.figure()
ax = fig.add_axes([0, 0, 1, 1])
ax.axis('off')

world.plot(ax=ax, column='2015', scheme='quantiles')

ax.margins(0)
ax.tick_params(left=False, labelleft=False, bottom=False, labelbottom=False)

plt.savefig('sample.png', bbox_inches="tight", pad_inches=0)

在上述所有三种情况下,得到的数字都是

【讨论】:

  • 太棒了,非常感谢您全面详细的回答!
猜你喜欢
  • 2020-09-30
  • 1970-01-01
  • 2019-04-23
  • 1970-01-01
  • 2012-03-08
  • 2012-05-19
  • 2021-08-17
  • 2012-08-24
  • 1970-01-01
相关资源
最近更新 更多