首页 > 解决方案 > 使用 python matplotlib 根据点密度绘制颜色网格

问题描述

问题是从文件中读取 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()

标签: pythonmatplotlib

解决方案


您可以创建只有两种颜色的颜色图,并将 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值很重要,可以全部添加为tick。然后,它们的位置也可以用来绘制网格线作为单元格之间的划分。

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)

等高线图


推荐阅读