use*_*097 3 python matplotlib geopandas
我最近开始使用 GeoPandas 来制作地图,发现它非常有用。我已经使用 Pandas 一段时间了,我发现迁移到 GeoPandas 相对轻松。但是,在使用 .dissolve() 函数对点进行分组后,我在地图上绘制点时遇到问题。
\n\n基本上,我从国家统计局邮政编码目录 (ONSPD) 下载了一系列英国邮政编码数据以及相关的经度和纬度值。经度和纬度值基于 CRS WGS84。我可以转换为 CRS OSGB36 并毫无问题地在地图上绘制所有点。但是,如果我使用 .dissolve() 方法根据其他变量(例如“group1”和“groups”)对点进行分组,我将无法再绘制这些点。
\n\n这是我迄今为止将所有点绘制在一起的代码:
\n\nimport pandas as pd\nimport geopandas as gif\nimport matplotlib.pyplot as plot\nimport shapely\n\n# Define a Pandas dataframe containing postcodes and \npostcodeDF = pd.DataFrame({\'pcd\': [\'RM175AG\', \'NP181PH\', \'LS8 1EN\', \'HG1 1XQ\', \'G11 6YB\', \'TN218AB\', \'GU138AL\', \'CV344BD\', \'YO126PH\', \'SO172WT\', \'PR2 8HN\', \'TF1 2HD\', \'M31 4FR\', \'CH460UB\', \'EX111LN\', \'TS214DX\', \'BN4 2LS\', \'FY8 1XL\', \'KA256BP\', \'DA1 1QR\'],\n \'ctry\': [\'E92000001\', \'W92000004\', \'E92000001\', \'E92000001\', \'S92000003\', \'E92000001\', \'E92000001\', \'E92000001\', \'E92000001\', \'E92000001\', \'E92000001\', \'E92000001\', \'E92000001\', \'E92000001\', \'E92000001\', \'E92000001\', \'E92000001\', \'E92000001\', \'S92000003\', \'E92000001\'],\n \'long\': [0.320423, -2.968257, -1.51314, -1.522386, -4.309171, 0.255878, -0.8502959999999999, -1.588886, -0.41805299999999995, -1.382926, -2.699804, -2.531778, -2.425061, -3.110276, -3.317868, -1.429442, -0.22178699999999998, -3.019257, -4.686457, 0.224912],\n \'lat\': [51.491329, 51.628333000000005, 53.840114, 54.002427000000004, 55.870383, 50.966097999999995, 51.275081, 52.280791, 54.296222, 50.921857, 53.780733999999995, 52.692078, 53.415147, 53.394830000000006, 50.758146, 54.680499, 50.84042, 53.753078, 55.749168999999995, 51.441911],\n \'group1\':[\'A\']*10 + [\'B\']*10,\n \'group2\':[True,False]*10})\n\n# Set up geodataframe, initially with CRS = WGS84 (since that matches the long and lat co-ordinates)\ncrs = {\'init\':\'epsg:4326\'}\ngeometry = [shapely.geometry.Point(xy) for xy in zip(postcodeDF[\'long\'], postcodeDF[\'lat\'])]\n\npostcodeGDF = gpd.GeoDataFrame(postcodeDF,\n crs = crs,\n geometry = geometry)\n\n# Convert geometry to OSGB36\npostcodeGDF = postcodeGDF.to_crs(epsg = 27700)\n\nprint(postcodeGDF)\nRun Code Online (Sandbox Code Playgroud)\n\n地理数据框包含以下信息:
\n\nctry group1 group2 lat long pcd \\\n0 E92000001 A True 51.491329 0.320423 RM175AG \n1 W92000004 A False 51.628333 -2.968257 NP181PH \n2 E92000001 A True 53.840114 -1.513140 LS8 1EN \n3 E92000001 A False 54.002427 -1.522386 HG1 1XQ \n4 S92000003 A True 55.870383 -4.309171 G11 6YB \n5 E92000001 A False 50.966098 0.255878 TN218AB \n6 E92000001 A True 51.275081 -0.850296 GU138AL \n7 E92000001 A False 52.280791 -1.588886 CV344BD \n8 E92000001 A True 54.296222 -0.418053 YO126PH \n9 E92000001 A False 50.921857 -1.382926 SO172WT \n10 E92000001 B True 53.780734 -2.699804 PR2 8HN \n11 E92000001 B False 52.692078 -2.531778 TF1 2HD \n12 E92000001 B True 53.415147 -2.425061 M31 4FR \n13 E92000001 B False 53.394830 -3.110276 CH460UB \n14 E92000001 B True 50.758146 -3.317868 EX111LN \n15 E92000001 B False 54.680499 -1.429442 TS214DX \n16 E92000001 B True 50.840420 -0.221787 BN4 2LS \n17 E92000001 B False 53.753078 -3.019257 FY8 1XL \n18 S92000003 B True 55.749169 -4.686457 KA256BP \n19 E92000001 B False 51.441911 0.224912 DA1 1QR \n\n geometry \n0 POINT (561188.9840165515 179484.0452796911) \n1 POINT (333075.0000681121 192612.9537310874) \n2 POINT (432134.031689987 438316.9950631865) \n3 POINT (431404.026064762 456371.9915770486) \n4 POINT (255609.0244790429 666546.0027781442) \n5 POINT (558502.0104336547 120942.0242662177) \n6 POINT (480294.0287511199 153509.0281225364) \n7 POINT (428143.9880141384 264818.0084207859) \n8 POINT (503054.9928648224 490110.0245871434) \n9 POINT (443470.0222579727 113781.050039533) \n10 POINT (353983.9862037547 431827.9554603411) \n11 POINT (364154.9903684837 310620.967712217) \n12 POINT (371845.0195746602 391010.9943895991) \n13 POINT (326267.022012488 389240.9700794323) \n14 POINT (307141.054758316 96222.92213930591) \n15 POINT (436886.0245473493 531865.0198253235) \n16 POINT (525299.9996502266 106049.9600256799) \n17 POINT (332890.0335889475 429005.9677596154) \n18 POINT (231483.9972917534 653913.0284422053) \n19 POINT (554726.0039838878 173783.0302315076) \nRun Code Online (Sandbox Code Playgroud)\n\n可用于绘制地图:
\n\n# Plot map\nfig, ax = plt.subplots(1,\n figsize = (4,5),\n dpi = 72,\n facecolor = \'lightblue\')\n\nax.set_position([0,0,1,1]) # Puts axis to edge of figure\nax.set_axis_off() # Turns axis off so facecolour applies to axis area as well as bit around the outside\nax.get_xaxis().set_visible(False) # Turns the x axis off so that \'invisible\' axis labels don\'t take up space\nax.get_yaxis().set_visible(False)\n\nlims = plt.axis(\'equal\')\n\n# N.B. Code to plot shapefile has been deleted for clarity\n\npostcodeGDF.plot(ax=ax)\n\nplt.show()\nRun Code Online (Sandbox Code Playgroud)\n\n地图(包括 shapefile 轮廓)如下所示:
\n\n\n\n但是,我想根据地理数据框中的其他变量对邮政编码进行分组(在本例中为变量“group1”和“group2”)(并最终为每个组绘制不同的颜色和标记\xe2\x80\x93虽然我还没有走到那一步)。我使用 .dissolve() 方法对点进行了分组。
\n\npostcodesGroupby = postcodeGDF.dissolve(by = [\'group1\',\'group2\'])\nprint(postcodesGroupby)\nRun Code Online (Sandbox Code Playgroud)\n\ngroupby 数据框如下所示:
\n\n geometry ctry\ngroup1 group2 \nA False (POINT (333075.0000681121 192612.9537310874), ... W92000004 \n True (POINT (255609.0244790429 666546.0027781442), ... E92000001 \nB False (POINT (326267.022012488 389240.9700794323), P... E92000001 \n True (POINT (231483.9972917534 653913.0284422053), ... E92000001 \n\n lat long pcd \ngroup1 group2 \nA False 51.628333 -2.968257 NP181PH \n True 51.491329 0.320423 RM175AG \nB False 52.692078 -2.531778 TF1 2HD \n True 53.780734 -2.699804 PR2 8HN \nRun Code Online (Sandbox Code Playgroud)\n\n但是,当我尝试使用以下方法绘制点时:
\n\npostcodesGroupby.plot(ax=ax)\nRun Code Online (Sandbox Code Playgroud)\n\n...地图上没有出现任何点。
\n\n我怀疑我错过了一些明显的东西,但我已经盯着代码看了一会儿,再也看不到树木了。任何有关如何解决此问题的建议将不胜感激。
\n问题是 geopandas 目前还不支持绘制多点(以及dissolve将点分组为多点的方法)。事实上,您得到的是空白图像而不是良好的错误消息,这有点不幸。
但是,刚刚合并了一个 PR,以添加对绘制多点的支持: https: //github.com/geopandas/geopandas/pull/683。所以这将在下一个 geopandas 版本中起作用。
目前的解决方法是绘制各个点,但必须使用适当的分组颜色,以添加反映这些组的列:
# add a new column with an integer indicating the group number
postcodeGDF['group'] = postcodeGDF.groupby(['group1','group2']).ngroup()
postcodeGDF.plot(column='group', categorical=True, legend=True)
Run Code Online (Sandbox Code Playgroud)
给出:
| 归档时间: |
|
| 查看次数: |
6394 次 |
| 最近记录: |