在Flourish中制作区域分布图时,数据不匹配通常表现为:数据表里的地区名称明明存在,地图上却大量灰色区域;或者颜色映射错位,A地区显示了B地区的数值。导致这种现象的原因很少出在Flourish平台本身,而集中在GeoJSON边界文件的属性结构上。

GeoJSON以FeatureCollection组织空间数据,每个Feature包含geometry和properties。Flourish在关联表格数据时,会根据你在数据映射步骤选择的“区域名称”列,与GeoJSON中properties对象里的某个字段做精确匹配。如果两边的大小写、空格、编码或命名不一致,匹配就会失败。因此修复工作要围绕属性键的唯一性和几何有效性展开。
一、检查GeoJSON的属性表与匹配字段
第一步是打开GeoJSON文件,确认properties中真正存在哪些字段。很多公开下载的边界文件使用的是NAME_1、NAME_2或ISO代码,而Flourish默认只读取常用字段如name。你可以用Python的json模块快速列出所有属性键,并抽样几个Feature查看取值是否规范。
执行下面的脚本会输出属性键列表,以及每个Feature的id和名称字段。注意在Flourish中,如果GeoJSON的Feature带有id成员,它有时会被优先用作匹配键。因此当你发现数据对不上时,要同时检查id和properties里目标字段的值是否与数据表完全一致。
import json
from collections import Counter
with open('region.geojson', encoding='utf-8') as f:
gj = json.load(f)
keys = Counter()
for feat in gj['features']:
keys.update(feat.get('properties', {}).keys())
print(feat.get('id'), feat.get('properties', {}))
print('属性键统计:', keys)
代码中feat.get('properties', {})能避免因缺失properties而报错,让你快速扫描整个文件。根据输出结果,判断是否需要重命名字段、删除重复字段或统一大小写。
二、修复属性键与坐标顺序的常见问题
当属性键与数据表列名不一致时,最直接的做法是在GeoJSON中重命名或复制出一个匹配字段。例如数据表使用region列,而边界文件里只有NAME_1,可以在Python中遍历所有Feature,把NAME_1的值写入一个新的region属性。这样上传到Flourish后,数据映射步骤就能识别到一致的字段。
除了属性问题,GeoJSON坐标顺序也可能导致渲染异常或匹配错乱。按照RFC 7946规范,多边形外环应为逆时针方向,内环为顺时针方向。部分软件导出的文件不符合这一约定,Flourish虽然通常能容错,但在复杂边界或带孔洞区域中容易出现填充错误。可以使用shapely的orient方法统一坐标方向。
import json
from shapely.geometry import shape, mapping
from shapely.geometry.polygon import orient
with open('raw.geojson', encoding='utf-8') as f:
gj = json.load(f)
for feat in gj['features']:
props = feat.get('properties', {})
if 'NAME_1' in props and 'region' not in props:
props['region'] = props['NAME_1']
geom = shape(feat['geometry'])
feat['geometry'] = mapping(orient(geom, sign=1.0))
with open('fixed.geojson', 'w', encoding='utf-8') as f:
json.dump(gj, f, ensure_ascii=False, indent=2)
这个脚本同时完成了两项工作:复制属性字段和标准化坐标方向。运行后重新上传GeoJSON,Flourish通常能正确渲染区域,并且数据表中的region字段能直接作为匹配键。注意代码中sign=1.0表示外环逆时针,这是GeoJSON规范推荐的方向。
三、处理重复要素、无效几何与字段编码
数据不匹配的另一个隐蔽原因是GeoJSON中存在重复的Feature。当两个区域拥有相同的名称或id时,Flourish无法确定将数值分配给哪一个,最终表现为该数值被跳过或随机落在其中一个区域上。可以通过Python字典统计匹配键的出现次数,找出重复项并手动合并或删除。
无效几何同样是常见干扰因素。某些边界文件在转换过程中会产生自相交多边形、空几何或重复坐标点,这些要素可能导致Flourish无法建立正确的区域映射。shapely的is_valid属性和make_valid函数可以检测并修复大多数拓扑错误。建议在导出前对所有几何做一次有效性检查,删除无法修复的要素,并输出日志记录被过滤的id。
from shapely.geometry import shape, mapping
from shapely.validation import make_valid
valid_features = []
for feat in gj['features']:
geom = shape(feat['geometry'])
if not geom.is_valid:
fixed = make_valid(geom)
if fixed.is_empty:
continue
feat['geometry'] = mapping(fixed)
valid_features.append(feat)
gj['features'] = valid_features
字段编码也要纳入检查范围。中文地区名称如果使用了不同的Unicode规范化形式,例如全角空格或不可见字符,会导致肉眼看着一样但程序无法匹配。可以用unicodedata.normalize统一为NFKC,并去除首尾空格。这一步能显著提高中文行政区划数据的匹配成功率。
四、验证修复结果并回传Flourish
修复完成后不要直接上传,先在本地做一次模拟匹配。读取你的数据表CSV,提取用于匹配的列,然后与GeoJSON属性字段逐一比对,输出缺失和多余的值。这个步骤可以帮你发现是否还有拼写差异、缩写差异或编码残留。
如果本地匹配通过,上传到Flourish后建议先使用单一分类变量测试,只绑定一个指标,查看地图着色是否与预期一致。确认无误后再逐步增加气泡大小、标签和工具提示字段。这样即使出现问题,也能快速定位是边界文件还是数据表导致的。
总结来说,Flourish地图数据不匹配的根源大多在GeoJSON的属性键、唯一性、几何有效性和坐标方向。通过脚本批量检查并修复这些细节,可以避免反复上传调试,也能让后续的交互式可视化更稳定。