Python:如何为具有不同颜色强度或不同圆形半径的坐标绘制热图?

4

假设有三个列表中的一些数据,例如:

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]

这段文字可以翻译为:可以这样理解: 在地图上,坐标为(latitudes[i], longitudes[i])的点出现了counts[i]次。
我想生成一个合适比例尺的热力图。坐标应该用填充色的圆表示。圆的直径应该以对应坐标的数量为基础确定。作为替代方案,我考虑用颜色强度表示数量。我不知道哪个更好,或者这两种表现方式是否可以结合使用。
如何实现这样的热力图呢?(我假设它被称为热力图?)
可能提到我处理的数据量很大:
- sum(counts) 约为 1,000,000 - 大约有 25,000 个不同的坐标。

1
也许这可以帮助 - https://dev59.com/SXE95IYBdhLWcg3wSsGD - Pushpak Dagade
3个回答

6

scatter方法是你要找的方法,它有两个可选参数,可以调整每个点的大小(使用关键字sizes)或颜色(使用关键字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')

您将获得更简洁的图表:

enter image description here

我当然不小心交换了纬度和经度轴,但您已经明白了 :)

太好了,谢谢!现在我也想缩放地图,因为仅仅缩放“计数”是不够的。请问您能告诉我如何做吗?我查找了scatter()方法,但是我没有找到任何参数来实现这一点。我应该在哪里告诉matplotlib将“地图”放大,以便点之间有更多的间隔? - Aufwind
抱歉我的英语不好。 :-) 我会再次尝试解释。你在答案中展示给我的东西很棒。我明白如何缩放圆圈。现在我想要实现的是使x和y轴“更长”。我目前正在探索mathplotlib库,我发现了这个:xmin,xmax = plt.xlim()。它现在返回-200.0和200.0。如果两个轴都返回-20000.0和20000.0,轴就会变得更长,保持比例,结果圆圈周围会有更多空间。目前它看起来像这样 - Aufwind
仅仅将纬度和经度按比例缩放,例如100,并不起作用。 :-) - Aufwind
有两个选项:(1)使用xlim和ylim来“缩放”到一个大陆,为每个大陆制作一个图像,或者(2)使用http://matplotlib.sourceforge.net/api/pyplot_api.html#matplotlib.pyplot.figure figsize设置英寸大小和/或dpi控制每英寸点数,制作一个非常大的图像。您还可以考虑非线性地缩放计数,例如通过将大小设置为s=counts*counts*COUNTS_TO_SIZE并调整常量,使最大的点不会太大...我将尝试提供一个示例并将其添加到答案中... - Yann
通过“缩放”,我指的是将xlim和ylim范围设置为总范围的较小集,因此在我的上面的示例中,我将执行plt.xlim(44,46)plt.ylim(-50,-30)仅绘制数据的左下角。 - Yann
显示剩余2条评论

0
在任何图形库的一般答案中,您都希望像这样做:
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值,具体取决于您在最终图像中想要的大小和要放入的值。如果发现计数过大而无法显示,并且在降低最大大小时较小的项目太小,则可以考虑使用对数比例而不是线性比例来表示强度。

使用实际图形库实现这一点应该很容易,但取决于库本身。


0

我对热力图不是很确定,但如果要用不同大小的彩色圆圈绘制图表,您可以使用以下代码:

   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]

或者你可以按照自己的喜好定义颜色。


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