【问题标题】:Heat World Map with MatPlotLib [duplicate]带有 MatPlotLib 的热世界地图 [重复]
【发布时间】:2014-05-06 06:08:51
【问题描述】:

我正在尝试将热图与我创建的世界地图结合起来。我得到的是一个包含 3 列的 CSV 文件。第一列包含国家名称,第二列和第三列分别包含纬度和经度。现在我写了一个类,它根据世界地图上的坐标绘制点。这很好用,但我现在想要的是一张热图,因为只有几个点一切看起来都很好,但我会得到很多点。所以根据一个国家的点数和指定的边界,应该实现热图。

import csv

class toMap:

    def setMap(self):
        filename = 'log.csv'
        lats, lons = [], []

        with open(filename) as f:
            reader = csv.reader(f)

            next(reader)

            for row in reader:
                lats.append(float(row[1]))
                lons.append(float(row[2]))

        from mpl_toolkits.basemap import Basemap
        import matplotlib.pyplot as plt
        import numpy as np

        map = Basemap(projection='robin', resolution='l', area_thresh=1000.0,
                      lat_0=0, lon_0=-130)
        map.drawcoastlines()
        map.drawcountries()
        map.fillcontinents(color='gray')
        #map.bluemarble()
        #map.drawmapboundary()
        map.drawmeridians(np.arange(0, 360, 30))
        map.drawparallels(np.arange(-90, 90, 30))

        x, y = map(lons, lats)
        map.plot(x, y, 'ro', markersize=3)

        plt.show()

def main():
    m = toMap()
    m.setMap()

以下是 CSV 的示例:

Vietnam,10.35,106.35
United States,30.3037,-97.7696
Colombia,4.6,-74.0833
China,35.0,105.0
Indonesia,-5.0,120.0
United States,38.0,-97.0
United States,41.7511,-88.1462
Bosnia and Herzegovina,43.85,18.3833
United States,33.4549,-112.0777

【问题讨论】:

  • 我很想看看你是如何构建 CSV 文件的,这看起来真的很有趣!!你现在的输出是多少?我猜您发布的图片是通用图片?
  • 您在上面看到的输出是我想要实现的,它不是我上面编写的代码的输出之一。它应该看起来像这样。我将编辑我的帖子并向您展示我的 CSV 文件的外观以及代码当前作为输出提供的内容。
  • 我在这里可能真的很愚蠢。但是,如果您在 CSV 文件中给出 x、y 坐标,那么您肯定可以用热图绘制这些坐标吗?我很确定我已经看到了与您提出的想法类似的想法;但我会看看我是否可以在午休时间找到这些例子
  • 你应该能够使用 cartopy 做你想做的事。看这里:stackoverflow.com/questions/13397022/…要根据某个数字选择国家的颜色,调用一个matplotlib colormap实例,其值在0到1之间。看这里的例子:stackoverflow.com/questions/9999010/…

标签: python matplotlib plot maps


【解决方案1】:

按照我上面评论中的相同逻辑,我对您的代码进行了一些更改以获得您想要的地图类型。

我的解决方案使用cartopy library

这是您的代码,以及我的更改(和 cmets):

import csv

class toMap:

def setMap(self):
    # --- Save Countries, Latitudes and Longitudes ---
    filename = 'log.csv'
    pais, lats, lons = [], [], []

    with open(filename) as f:
        reader = csv.reader(f)

        next(reader)

        for row in reader:
            pais.append(str(row[0]))
            lats.append(float(row[1]))
            lons.append(float(row[2]))

    #count the number of times a country is in the list
    unique_pais = set(pais)
    unique_pais = list(unique_pais)

    c_numero = []

    for p in unique_pais:
        c_numero.append(pais.count(p))
        print p, pais.count(p)

    maximo = max(c_numero)

    # --- Build Map ---
    import cartopy.crs as ccrs
    import cartopy.io.shapereader as shpreader
    import matplotlib.pyplot as plt
    import matplotlib as mpl
    import numpy as np

    cmap = mpl.cm.Blues

    # --- Using the shapereader ---
    test = 0
    shapename = 'admin_0_countries'
    countries_shp = shpreader.natural_earth(resolution='110m',
                                            category='cultural', name=shapename)

    ax = plt.axes(projection=ccrs.Robinson())
    for country in shpreader.Reader(countries_shp).records():
        nome = country.attributes['name_long']
        if nome in unique_pais:
            i = unique_pais.index(nome)
            numero = c_numero[i]
            ax.add_geometries(country.geometry, ccrs.PlateCarree(),
                              facecolor=cmap(numero / float(maximo), 1),
                              label=nome)
            test = test + 1

        else:
            ax.add_geometries(country.geometry, ccrs.PlateCarree(),
                              facecolor='#FAFAFA',
                              label=nome)

    if test != len(unique_pais):
        print "check the way you are writting your country names!"

    plt.show()


def main():
    m = toMap()
    m.setMap()

按照您的逻辑,我制作了一个包含一些国家/地区的自定义 log.csv 文件,这是我的地图:

(我使用了 Blues 颜色图,比例的最大值是根据一个国家/地区在您的 csv 文件中出现的最大次数来定义的。)

根据您在编辑问题之前的示例图片,我认为这正是您想要的!

【讨论】:

  • 正是我想要的,谢谢。在我的示例中使用 gl =ax.gridlines(draw_labels=False) 在上面添加网格。只是为了完整性;)
猜你喜欢
  • 2022-01-13
  • 2013-12-28
  • 2012-12-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多