【问题标题】:Python: How to plot a heatmap for coordinates with different color intensity or different radius of circles?Python:如何为具有不同颜色强度或不同圆半径的坐标绘制热图?
【发布时间】:2012-03-22 23:26:41
【问题描述】:

给定三个列表中的一些数据,例如:

latitudes = [50.877979278564,48.550216674805,47.606079101562,50.772491455078,42.451354980469,43.074657440186,44.044174194336,44.563243865967,52.523406982422,50.772491455078]
longitudes = [4.700091838837, 9.038957595825, -122.333000183105, 7.190686225891, -76.476554870605, -89.403335571289, -123.070274353027, -123.281730651855, 13.411399841309, 7.190686225891]
counts = [15, 845, 2, 50, 95, 49, 67, 32, 1, 88]

可以解释为:i的坐标即(latitudes[i]longitudes[i])在地图上出现counts[i]次。

我想生成具有适当比例的热图。坐标应由彩色圆圈表示。圆的直径应该以某种方式代表相应坐标的计数。

(作为替代方案,我考虑过用颜色强度来表示计数。我不知道哪个最好,或者这两种表示是否可以结合使用。)

我怎样才能实现这样的热图? (我假设它是这样称呼的?)

也许提及我正在处理的数据量是相关的:

  • sum(counts) 大约是 1.000.000
  • 大约有 25.000 个不同的坐标。

【问题讨论】:

标签: python plot matplotlib heatmap


【解决方案1】:

scatter 是您正在寻找的方法,它有两个可选参数来调整大小(使用关键字size 或只是s)或颜色(使用关键字colorc ) 的每一点,或者你可以同时做这两个。颜色或热图效果可能更适合您拥有的点密度。

以下是使用此方法的示例:

import matplotlib.pyplot as plt
import numpy as np

NPOINTS = 1000

np.random.seed(101)
lat = np.random.random(NPOINTS)*8+44
lon = np.random.random(NPOINTS)*100-50
counts = np.random.randint(0,1000,NPOINTS)

plt.subplot(211)
plt.scatter(lat, lon, c=counts)
plt.colorbar()
plt.subplot(212)
plt.scatter(lat, lon, s=counts)

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

导致:

如果您选择使用size,您可能需要调整计数值以获得不那么拥挤的图,例如通过扩展上面的示例:

plt.figure()
COUNT_TO_SIZE = 1./10
plt.scatter(lat, lon, s=counts*COUNT_TO_SIZE)
plt.savefig('scatter_example2.png')

你会得到一个更清晰的情节:

我当然不小心从它们的正常坐标轴上交换了纬度和经度,但你明白了 :)

【讨论】:

  • 这太好了,谢谢!现在我也在尝试缩放地图,因为缩放“计数”是不够的。能告诉我这是怎么做到的吗?我查找了scatter() 方法,但找不到任何参数来实现它。我在哪里可以告诉 matplotlib 将“地图”设置得更大,这样点就会变得更加分离?
  • 我很好奇,你所说的“仅按比例计算”是什么意思是不够的。您是否使用计数来设置大小或颜色?如果您使用它来设置颜色并且生成的圆圈太密集,您可以将大小s 设置为标量:s=5。这将每个点设置为具有相同的大小。默认大小为 20,这表示直径的平方,因此 s=5 是一半大小的圆。
  • 对不起我的英语不好。 :-) 我会再次尝试解释。您在回答中向我展示的内容效果很好。我了解如何缩放圆圈。我现在想要实现的是让 x 和 y 轴“更长”。我目前正在探索 mathplotlib 库,我发现了这个:xmin, xmax = plt.xlim()。它现在返回 -200.0 和 200.0。如果两个轴都将返回 -20000.0 和 20000.0,则轴将更长地保留比例,从而使圆圈周围有更多空间。目前它看起来像this
  • 只是缩放纬度和经度,例如100 似乎不起作用。 :-)
  • 有两种选择:(1) 使用 xlim 和 ylim 来“放大”一个大陆,为每个大陆制作一个图形,或者 (2) 使用matplotlib.sourceforge.net/api/… @987654337 制作一个非常大的图形@ 以英寸为单位设置大小,或dpi 以控制每英寸点数。您还可以考虑非线性缩放计数,也许通过将大小设置为s=counts*counts*COUNTS_TO_SIZE 并调整常量以使最大的点不会太大...我将尝试提出一个示例并将其添加到答案中...
【解决方案2】:

我不太确定热图,但可以使用不同大小的彩色圆圈进行绘制:

   from matplotlib import pyplot    

   pyplot.scatter(longitudes,latitudes,counts,c=rgb)
   pyplot.show()

其中 rgb 是用户定义的 rgb 值的二维数组,类似于:

   maxcount = float(max(counts))
   rgb = [[ 1, 0.5, x/maxcount ] for x in counts]

或者你想定义你的颜色。

【讨论】:

    【解决方案3】:

    在任何图形库的一般答案中,您都希望执行以下操作:

    maxSize = 10 #The maximum radius of the circles you wish to draw.
    maxCount = max(counts)
    
    for lat, long, count in zip(latitudes, longitudes, counts):
        draw_circle(lat, long, count/maxCount*maxSize) #Some drawing library, taking x, y, radius.
    

    zip() 允许您加入三个列表并在一个循环中迭代它们。

    将计数除以最大计数可以得到一个相对的大小比例,然后将其乘以您希望圆圈的大小。如果你也想改变颜色,你可以这样做:

    maxSize = 10 #The maximum radius of the circles you wish to draw.
    maxCount = max(counts)
    
    for lat, long, count in zip(latitudes, longitudes, counts):
        intensity = count/maxCount
        draw_circle(lat, long, intensity*maxSize, Color(intensity*255, 0, 0)) #Some drawing library, taking x, y, radius, colour.
    

    随着强度的增加产生从黑色到红色的滑动刻度。

    您可能需要调整纬度和经度值以生成合理的 x 和 y 值,具体取决于您希望在最终图像中使用的大小以及要输入的值。如果您发现计数太大而无法显示,并且在降低最大尺寸时较小的项目太小,您可能需要考虑对数刻度而不是线性强度。

    用一个实际的图形库来实现这一点应该很简单,但取决于库本身。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-23
      • 2018-01-02
      • 2023-04-03
      • 1970-01-01
      • 2020-10-06
      • 2019-03-08
      相关资源
      最近更新 更多