【问题标题】:draw a color grid based on points density using python matplotlib使用 python matplotlib 根据点密度绘制颜色网格
【发布时间】:2020-08-27 09:45:22
【问题描述】:

问题是从一个文件中读取 10,000 个坐标点,并根据网格上每个块的密度创建一个彩色网格。 x 轴的范围是 [-73.59, -73.55],y 轴的范围是 [45.49,45.530]。我的代码将绘制一个具有许多不同颜色的网格,现在我需要一个功能来只为具有特定密度 n 的网格着色,例如,n = 100,只有具有 100 点或更高点的网格才会被着色为黄色,其他网格将是黑色的。

我刚刚添加了一个指向我的 shapefile 的链接 https://drive.google.com/open?id=1H-8FhfonnPrYW9y7RQZDtiNLxVEiC6R8

import numpy as np
import matplotlib.pyplot as plt
import shapefile

grid_size = 0.002
x1 = np.arange(-73.59,-73.55,grid_size)
y1 = np.arange(45.49,45.530,grid_size)
shape = shapefile.Reader("Shape/crime_dt.shp",encoding='ISO-8859-1')
shapeRecords = shape.shapeRecords()

x_coordinates=[]
y_coordinates=[]

# read all points in .shp file, and store them in 2 lists.
for k in range(len(shapeRecords)):
    x = float(shapeRecords[k].shape.__geo_interface__["coordinates"][0])
    y = float(shapeRecords[k].shape.__geo_interface__["coordinates"][1])
    x_coordinates.append(x)
    y_coordinates.append(y)

plt.hist2d(x_coordinates,y_coordinates,bins=[x1,y1])
plt.show()

【问题讨论】:

  • 由于我们没有您的 shapefile,您可能想要制作一个可复制的玩具示例minimal reproducible example
  • @anishtain4 我刚刚添加了一个指向我的 shapefile 的链接,数据是开源的,所以没问题。

标签: python matplotlib


【解决方案1】:

您可以创建一个只有两种颜色的颜色图,并将 vmin 和 vmax 设置为围绕所需的枢轴值对称。

您可以选择将每个 bin 的值放在单元格内,而枢轴值决定文本颜色。

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap

grid_size = 0.002
x1 = np.arange(-73.59, -73.55, grid_size)
y1 = np.arange(45.49, 45.530, grid_size)

# read coordinates from file and put them into two lists, similar to this
x_coordinates = np.random.uniform(x1.min(), x1.max(), size=40000)
y_coordinates = np.random.uniform(y1.min(), y1.max(), size=40000)
pivot_value = 100
# create a colormap with two colors, vmin and vmax are chosen so that their center is the pivot value
cmap = ListedColormap(['indigo', 'gold'])
# create a 2d histogram with xs and ys as bin boundaries
binvalues, _, _, _ = plt.hist2d(x_coordinates, y_coordinates, bins=[x1, y1], cmap=cmap, vmin=0, vmax=2*pivot_value)
binvalues = binvalues.astype(np.int)
for i in range(len(x1) - 1):
    for j in range(len(y1) - 1):
        plt.text((x1[i] + x1[i + 1]) / 2, (y1[j] + y1[j + 1]) / 2, binvalues[i, j],
                 color='white' if binvalues[i, j] < pivot_value else 'black',
                 ha='center', va='center', size=8)
plt.show()

PS:如果 bin 值非常重要,您可以将它们全部添加为刻度。然后,它们的位置也可以用来绘制网格线作为单元格之间的划分。

plt.yticks(y1)
plt.xticks(x1, rotation=90)
plt.grid(True, ls='-', lw=1, color='black')

要根据这些数据获取轮廓,您可以使用生成的矩阵plt.contourf。 (您可能想使用np.histogram2d 直接创建矩阵。)

plt.contourf((x1[1:]+x1[:-1])/2, (y1[1:]+y1[:-1])/2, binvalues.T, levels=[0,100,1000], cmap=cmap)

【讨论】:

  • nvm,它有效,我没有从我的代码中删除 plt.hist2d(x_coordinates,y_coordinates,bins=[x1,y1])。
  • 这很有帮助,我很感激!实际上我不需要在每个网格中显示数字,所以我删除了最后一个循环部分。我只是想了解 vmax = 2*pivot_value 的工作原理
  • 是的,请随意更改,代码只是一个示例。它还可以帮助调试,因为根据枢轴值,所有东西可能只有一种颜色。使用colormap 时,将 vmin 的值分配给最低颜色,将 vmax 分配给最高颜色。当只有两种颜色时,中心值 ((vmin+vmax)/2) 是单元格改变颜色的枢轴值。 (高于 vmax 的值也会获得最高颜色。)
  • 现在我明白你为什么将 2*pivot 分配给 vmax 了,它会使所有数字高于枢轴一个颜色,非常详细的解释!顺便说一句,枢轴号会包括还是不包括在内?
  • 在这种情况下它是黄色的。但由于这些是浮点运算,在某些情况下,枢轴值可能会以另一种方式倾斜。您可以设置vmax=2*pivot_value - 0.001 以确保枢轴始终包含在高位中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-05-07
  • 2013-03-11
  • 2016-09-27
  • 1970-01-01
  • 2015-11-03
  • 2020-02-12
  • 1970-01-01
相关资源
最近更新 更多