python - 使用 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()
解决方案
您可以创建只有两种颜色的颜色图,并将 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)
推荐阅读
- excel - 使用查找函数、循环和变量工作表名称
- node.js - 在 Mojave OS 上与 safari 12 一起使用时遇到 npm selenium-webdriver 问题
- python - 如何在python中分配新数组而不是构建指针
- ios - 如何在单击按钮时删除任何 MKPointAnnotation
- android - 您的应用正在使用包含 SQL 注入漏洞的内容提供程序
- ruby - irb 历史保存但不加载
- c# - 编辑器脚本附加到的 Unity Access 脚本
- sql - 为多列构建 TYPE
- python - 如何将随机值从一个元素传输到另一个元素?
- php - 如何将数据存储在 WordPress 的全局变量中?