为什么我的Cartopy地图中谷歌瓦片看起来很模糊?

10

我对 Cartopy 渲染 Google 地图瓦片的结果感到有些困惑。与标准的 Google 地图相比,地图看起来非常差。

示例(代码来源于 https://ocefpaf.github.io/python4oceanographers/blog/2015/06/22/osm/):

import matplotlib.pyplot as plt

import cartopy.crs as ccrs
from cartopy.io import shapereader
from cartopy.mpl.gridliner import LONGITUDE_FORMATTER, LATITUDE_FORMATTER

def make_map(projection=ccrs.PlateCarree()):
    fig, ax = plt.subplots(figsize=(9, 13),
                           subplot_kw=dict(projection=projection))
    gl = ax.gridlines(draw_labels=True)
    gl.xlabels_top = gl.ylabels_right = False
    gl.xformatter = LONGITUDE_FORMATTER
    gl.yformatter = LATITUDE_FORMATTER
    return fig, ax
import cartopy.io.img_tiles as cimgt

extent = [-39, -38.25, -13.25, -12.5]

request = cimgt.GoogleTiles()

fig, ax = make_map(projection=request.crs)
ax.set_extent(extent)

ax.add_image(request, 10)

生成的图片如下:

Poor resolution

与相同图片在链接网站上的显示效果相比,看起来非常模糊——请注意标签和街道号码的像素化呈现:

enter image description here

更改缩放级别似乎没有改善情况。

这是我正在使用Cartopy和googletiles()处理的另一个地图示例:

very poor

相同的地图在Google Maps中显示结果如下:

google map

有人知道这个奇怪问题的原因以及如何解决吗?


可能是mpl后端引起的问题吗?matplotlib.get_backend()返回什么? - Daniel Kirkham
@DanielKirkham 我在我的Jupyter笔记本上得到了'module://ipykernel.pylab.backend_inline',在我的ipython控制台上得到了'MacOSX'。两者都给出了相同的结果。 - stm4tt
1
我对cartopy的行为一无所知,但最近我发现了salem,它可以在谷歌图片上做一些很酷的事情。http://salem.readthedocs.io/en/latest/auto_examples/plot_googlestatic.html#sphx-glr-auto-examples-plot-googlestatic-py - Ray Bell
2个回答

12
这个问题也在cartopy问题跟踪器https://github.com/SciTools/cartopy/issues/1048上提出,建议设置interpolation=关键字参数。这是imshow的标准matplotlib插值,文档位于https://matplotlib.org/gallery/images_contours_and_fields/interpolation_methods.html
我们在问题跟踪器中确定,最接近的插值是你在这里看到的。将其更改为bilinear可以得到很好的结果,并且使用不同的插值方案可以获得更好的结果。例如,spline36方案会产生非常愉悦的图像...
因此,使用您的示例代码:
import matplotlib.pyplot as plt
  
import cartopy.crs as ccrs
from cartopy.io import shapereader
from cartopy.mpl.gridliner import LONGITUDE_FORMATTER, LATITUDE_FORMATTER

import cartopy.io.img_tiles as cimgt

extent = [-39, -38.25, -13.25, -12.5]

request = cimgt.OSM()

fig = plt.figure(figsize=(9, 13))
ax = plt.axes(projection=request.crs)
gl = ax.gridlines(draw_labels=True, alpha=0.2)
gl.xlabels_top = gl.ylabels_right = False
gl.xformatter = LONGITUDE_FORMATTER
gl.yformatter = LATITUDE_FORMATTER

ax.set_extent(extent)

ax.add_image(request, 10)

plt.show()

我们得到:

Nearest interpolation

要设置bilinear插值,我们可以将add_image行更改为:

ax.add_image(request, 10, interpolation='bilinear')

Bilinear interpolation

更好的是,让我们尝试使用 spline36 和 {{}}:

ax.add_image(request, 10, interpolation='spline36')

High order spline interpolation

将这些图像并排放置:

Side-by-side comparisson

需要注意的是(如https://github.com/SciTools/cartopy/issues/1048#issuecomment-417001744所指出的),当瓦片被绘制在非本机投影上时,有一个注意事项。在这种情况下,我们有两个变量需要配置:

  1. 从本地投影到目标投影的重新网格化分辨率
  2. 重投影图像渲染的插值方案(这就是我们在此答案中更改的内容)。

2
这个选项已经被弃用了吗?在尝试保存图形时,我收到了一个错误TypeError: draw() got an unexpected keyword argument 'interpolation' - akozi

2

接受的答案中有一个小笔误。

ax.add_image(request, 10, interpolation='spine36')

应该是

ax.add_image(request, 10, interpolation='spline36')

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接