考虑包含以下数据的CSV文件:
weight,lat,long
9876,23.44,88.15
1234,27.11,55.33
....
从这些数据创建加权热图的最简单方法是什么?
所有语言的答案均可接受。
答案 0 :(得分:0)
使用matplotlib我能够让它工作:
import csv
import matplotlib
import matplotlib.pyplot as plt
with open('data.csv') as f:
r = csv.reader(f)
C, Y, X = zip(*r)
X = [float(x) for x in X]
Y = [float(y) for y in Y]
fig = plt.figure()
ax = fig.add_subplot(111)
ax.hexbin(X, Y, C, gridsize=200)
plt.show()
然而,gridsize=200
的分辨率不够好,而且当使用更高的值时,matplotlib会在大约1000行的数据CSV文件中使用大量内存并且速度极慢。
似乎是hexbin()
has performance issues已知的问题。
答案 1 :(得分:0)
这是我最近建立的类似地图的衍生产品...但是,在最多缩放级别,如果存在重叠,则会合并标记,因此您可能希望删除该功能。它还使用了5个“加热”步骤,这是上一步的两倍,因此您可能还想在那里进行一些更改。而且,如果您使用此文字代码,则会查找一些标记图标:1.png
,2.png
... 7.png
:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Transaction Mapping</title>
<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?sensor=false"></script>
<style>
#wrap {width:960px;margin-right:auto;margin-left:auto;position:relative;}
#map_canvas {width:100%;height:700px;}
#legend_values {position:relative; top:-700px; left:200px;}
table {border-collapse:collapse;}
</style>
</head>
<body>
<div id="wrap">
<?php
if (is_uploaded_file($_FILES['upfile']['tmp_name'])){
$weights=array();
$lats=array();
$lngs=array();
$hdr=(isset($_REQUEST["hdr"]))?$_REQUEST["hdr"]:$hdr=0;
$file=$_FILES["upfile"]["tmp_name"];
$data=fopen($file,'r');
while($row=fgets($data)){
str_replace("\n","",$row);
str_replace("\r","",$row);
if(strlen($row)>0){
if($hdr<1){
$cells=explode(",",$row);
array_push($weights,$cells[0]);
array_push($lats,$cells[1]);
array_push($lngs,$cells[2]);
}
$hdr--;
}
}
$c=0;?>
<div id="map_canvas"></div>
<div id="legend_values"></div>
<script type="text/javascript">
<?php
echo "var data=[";
for($i=0;$i<count($weights);$i++){
if($c>0){echo ",";}
echo "[".$weights[$i].",".$lats[$i].",".$lngs[$i]."]";
$c++;
}
echo "];\n";
?>
var shopsToShow=Array();
var openingWindow;
var map;
var placesToFilter=Array();
var MyInfoWindow = new google.maps.InfoWindow({content: 'Loading...'});
var bounds2 = new google.maps.LatLngBounds();
var myOptions = {
zoom: 9,
mapTypeControl: false,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
for(i=0;i<data.length;i++){
var a=new Object();
a.weight=data[i][0];
a.lat=data[i][1];
a.lng=data[i][2];
placesToFilter.push(a);
}
map = new google.maps.Map(document.getElementById('map_canvas'),myOptions);
for(i=0;i<placesToFilter.length;i++){
if(placesToFilter[i].lng!=0){
var point2=new google.maps.LatLng(placesToFilter[i].lat,placesToFilter[i].lng);
bounds2.extend(point2);
}
}
google.maps.event.addListener(map, 'bounds_changed', function() {filterAnnotations();});
map.fitBounds(bounds2);
function filterAnnotations(){
for (x in shopsToShow) {
shopsToShow[x].setMap(null);
google.maps.event.clearListeners(shopsToShow[x], 'click');
}
shopsToShow=new Array();
var found,checkingLocation;
//20 in the below lines is the height and width of the graphic you're using for the marker
scaleFactorLongitude = document.getElementById('map_canvas').offsetWidth/20;
scaleFactorLatitude = document.getElementById('map_canvas').offsetHeight/20;
var bounds=map.getBounds();
var latDelta=(bounds.getNorthEast().lat()-bounds.getSouthWest().lat())/scaleFactorLatitude;
var longDelta=(bounds.getNorthEast().lng()-bounds.getSouthWest().lng())/scaleFactorLongitude;
for (m=0; m<placesToFilter.length; m++) {
checkingLocation=placesToFilter[m];
checkingLatitude = checkingLocation.lat;
checkingLongitude = checkingLocation.lng;
found=false;
for (x in shopsToShow) {
if(Math.abs(shopsToShow[x].getPosition().lat()-checkingLatitude) < latDelta &&
Math.abs(shopsToShow[x].getPosition().lng()-checkingLongitude) <longDelta ){
shopsToShow[x].weight=(shopsToShow[x].weight*1)+(placesToFilter[m].weight*1);
found=true;
break;
}
}
if ((!found)&&(checkingLongitude!=0)) {
var point=new google.maps.LatLng(checkingLatitude,checkingLongitude);
if (bounds.contains(point) == true){
var marker = new google.maps.Marker({position: point,map: map, icon:'7.png'});
marker.weight=placesToFilter[m].weight;
shopsToShow.push(marker);
}
}
}
//adjust colors and clickability
var maxweight=shopsToShow[0].weight*1;
var minweight=shopsToShow[0].weight*1;
for (i=1;i<shopsToShow.length;i++) {
if (shopsToShow[i].weight*1>maxweight) {
maxweight=shopsToShow[i].weight*1;
}
if (shopsToShow[i].count*1<minweight) {
minweight=shopsToShow[i].weight*1;
}
}
var gap=maxweight-minweight;
var roundToNearest=10;
if(gap<160){
roundToNearest=5;
}
if(gap<16){
roundToNearest=1;
}
//determine steps
cat=[];
var step=Math.ceil((gap/16)/roundToNearest)*roundToNearest;
for(i=0;i<5;i++){
var n=step*Math.pow(2,i);
cat.push(n);
}
//Math.ceil(number/10)*10;
if(gap==0){
cat=[1,2,3,4,5];
}
document.getElementById('legend_values').innerHTML="<table id=\"nudge\"><tr><td align=\"center\" width=\"30px\" style=\"padding:3px 10px 3px 10px;background-color:#F0F;\">≤"+cat[0]+"</td><td align=\"center\" width=\"30px\" style=\"padding:3px 10px 3px 10px; background-color:#0F0;\">≤"+cat[1]+"</td><td align=\"center\" width=\"30px\" style=\"padding:3px 10px 3px 10px; background-color:#FF0;\">≤"+cat[2]+"</td><td align=\"center\" width=\"30px\" style=\"padding:3px 10px 3px 10px; background-color:#F60;\">≤"+cat[3]+"</td><td align=\"center\" width=\"30px\" style=\"padding:3px 10px 3px 10px; background-color:#F00;\">≤"+cat[4]+"</td></tr></table>";
document.getElementById('legend_values').style.left=((960-document.getElementById('nudge').offsetWidth*1)/2)+'px';
for (var i = 0; i < shopsToShow.length; i++) {
var marker = shopsToShow[i];
var ic;
//here you're setting the proper icons, so if you were to keep this as is, you'd need to have 7.png, 6.png, etc
if(marker.weight<cat[4]){ic=7;}
if(marker.weight<cat[3]){ic=6;}
if(marker.weight<cat[2]){ic=5;}
if(marker.weight<cat[1]){ic=4;}
if(marker.weight<cat[0]){ic=1;}
marker.setIcon(ic+".png");
google.maps.event.addListener(marker, 'click', function () {
MyInfoWindow.setContent('Weight:'+this.weight);
MyInfoWindow.open(map, this);
});
}
}
</script>
<?php
}
else{?>
<form action="" method="post" enctype="multipart/form-data">
<table><tr><td align="right">File:</td><td><input type="file" name="upfile" id="file" /></td></tr>
<tr><td align="right">First Row is Header:</td><td><input type="checkbox" name="hdr" id="hdr" value="1"/></td></tr>
<tr><td colspan="2" align="center"><input type="submit" name="submit" value="Upload" /></td></tr></table>
</form>
<?php
}
?>
</div>
</body>
</html>