Overlaid boundary and point Altair plots are not aligning

34 Views Asked by At

I've got a layer map plot in Altair of London that I was struggling to flip - Solving upside plot and projection problems in Geopandas and Altair

However, a more troubling problem is that I've got a dataframe with shapefiles that look a bit like shape_data and the points are the points.

    Postcode    Ward    lat long    geometry
0   N16 5RF Springfield 51.572046   -0.075572   POINT (-0.07557 51.57205)
1   N16 5RF Springfield 51.572046   -0.075572   POINT (-0.07557 51.57205)
2   N16 5RF Stamford Hill West  51.572046   -0.075572   POINT (-0.07557 51.57205)
3   N16 5RF Stamford Hill West  51.572046   -0.075572   POINT (-0.07557 51.57205)

The shape_data looks a bit like this:

    NAME    GSS_CODE    DISTRICT    LAGSSCODE   HECTARES    NONLD_AREA  geometry
555 Hoxton East & Shoreditch    E05009377   Hackney E09000012   102.355 0.0 POLYGON ((532942.69738 -182547.89554, 532938.50065 -182560.80185, 532968.49618 -182570.49907, 533030.40010 -182589.10375, 533033.09623 -182616.59588, 533034.39895 -182629.40221, 533033.89601 -182758.79517, 533032.79941 -182788.39670, 533031.99964 -182826.59577, 533031.29881 -182869.10360, 533033.69812 -182877.70114, 533035.99850 -182888.59802, 533039.40371 -182920.99874, 533042.70173 -182947.60113, 533055.00336 -182961.49715, 533061.50047 -182969.10497, 533063.99872 -182973.60369, 533068.69841 -182994.69765, 533071.89749 -183013.50227, 533073.99998 -183036.29574, 533074.40399 -183054.20062, 533072.90339 -183085.20174, 533073.80210 -183093.49937, 533070.80090 -183130.69872, 533066.39804 -183178.80495, 533061.89623 -183225.90147, 533060.50282 -183259.90173, 533060.19775 -183329.40184, 533026.50019 -183325.80287, 532990.79907 -183322.10393, 532960.69635 -183321.50410, 532923.89864 -183320.50439, 532838.90031 -183317.69519, 532835.99805 -183357.40383, 532833.59874 -183382.29670, 532829.59988 -183384.19616, 532824.19937 -183382.29670, 532809.80349 -183375.29870, 532736.39771 -183338.09935, 532718.10192 -183373.39925, 532688.60109 -183433.50204, 532625.60058 -183559.99583, 532590.30347 -183629.69588, 532627.70307 -183662.39652, 532660.09791 -183691.59816, 532691.50335 -183718.20055, 532725.29986 -183746.50245, 532745.20344 -183759.49873, 532767.39914 -183769.29592, 532786.00000 -183775.10426, 532799.80223 -183774.00457, 532801.50071 -183770.39561, 532815.69871 -183774.50443, 532869.70386 -183787.80063, 532922.90099 -183798.69751, 532939.10254 -183801.89659, 532951.99781 -183804.19593, 532964.00262 -183804.49585, 532992.59649 -183799.49728, 533054.09640 -183786.70094, 533142.49995 -183769.39589, 533255.49851 -183747.40219, 533293.40106 -183740.90405, 533369.70085 -183724.99860, 533386.70217 -183721.99946, 533449.39761 -183711.00261, 533476.69701 -183705.40421, 533475.40254 -183547.39944, 533473.20111 -183489.89590, 533470.49673 -183412.99791, 533467.60271 -183358.40354, 533467.29764 -183337.19961, 533466.70400 -183324.70319, 533465.59916 -183312.99654, 533471.89839 -183259.10196, 533475.30360 -183235.09883, 533478.79950 -183205.89719, 533479.69821 -183182.70383, 533479.20351 -183162.79953, 533478.40374 -183142.09546, 533477.00208 -183129.79898, 533474.70171 -183093.19945, 533472.79710 -183073.79501, 533471.99733 -183066.29715, 533471.09862 -183056.20004, 533470.80179 -183051.40142, 533463.19985 -182999.59625, 533460.00076 -182978.50228, 533452.29988 -182940.20325, 533447.09724 -182915.50032, 533440.30331 -182892.29696, 533436.09833 -182878.80082, 533429.60122 -182847.19987, 533432.89925 -182846.50007, 533443.99710 -182843.30099, 533460.39653 -182839.40210, 533470.49673 -182836.70287, 533487.30016 -182832.80399, 533501.69604 -182828.99508, 533524.30399 -182823.29671, 533540.59624 -182819.89768, 533558.70239 -182815.69889, 533567.40093 -182813.39954, 533575.10182 -182807.90112, 533580.60127 -182803.80229, 533560.10405 -182777.69976, 533539.30176 -182749.59781, 533502.99876 -182707.19994, 533478.29655 -182683.59670, 533543.80356 -182668.60099, 533541.70107 -182637.99975, 533530.10027 -182597.50134, 533523.80105 -182583.69530, 533523.80105 -182570.99893, 533523.99893 -182557.90268, 533525.40059 -182539.69789, 533528.09672 -182510.69619, 533532.10382 -182466.29890, 533543.30062 -182350.40208, 533579.80150 -182355.20070, 533590.80041 -182303.69545, 533595.59904 -182273.90397, 533595.30222 -182262.49724, 533593.19973 -182228.29703, 533590.50359 -182212.80146, 533589.10193 -182204.90372, 533587.60133 -182196.69607, 533578.10302 -182158.19709, 533574.09592 -182138.80265, 533568.80259 -182118.89834, 533567.30199 -182113.39992, 533549.20408 -182097.40450, 533530.29815 -182119.09829, 533501.90216 -182107.50161, 533447.50125 -182086.89750, 533425.99813 -182076.50048, 533411.89908 -182041.60047, 533410.70354 -182037.90153, 533320.19751 -182053.39709, 533250.89777 -182075.90065, 533230.49949 -182082.49876, 533215.79854 -182024.09548, 533198.59935 -181977.99868, 533184.59923 -181948.19721, 533182.39780 -181945.39801, 533167.49898 -181925.30376, 533146.80387 -181897.90160, 533119.19941 -181869.79965, 533078.89755 -181840.49803, 532946.10259 -181894.90246, 532955.69985 -181928.00299, 532965.80005 -181968.70134, 532978.10168 -182037.30170, 532989.19953 -182089.29682, 532993.70133 -182136.00345, 532998.20314 -182237.50439, 532999.20079 -182259.79801, 533004.70024 -182293.29842, 532983.60113 -182292.39868, 532941.09784 -182294.29814, 532941.60079 -182350.20213, 532918.30025 -182358.99961, 532920.40274 -182368.09701, 532929.29916 -182396.79880, 532944.89882 -182436.89732, 532963.69755 -182460.80047, 532951.39592 -182511.79588, 532942.69738 -182547.89554))

I can write the code in Python's Altair to plot the data

london_wards_map = alt.Chart(london_wards_gpd).mark_geoshape(
    fill=None,  # No fill
    stroke='darkgray',  # Black stroke
    strokeWidth=1  # Stroke width ).encode(
    tooltip='NAME:N'  # Replace 'NAME' with the actual name of the column that contains the ward names ).properties(
    width=800,
    height=600 ).project(
    type='identity')

postcode_meals.crs = 4326
points = alt.Chart(postcode_meals).mark_circle(color='#008751').encode(
    longitude='long:Q',
    latitude='lat:Q',
    size=alt.Size('count:Q', scale=alt.Scale(domain=[postcode_meals['count'].min(), postcode_meals['count'].max()], range=[10, 1000])),  # Adjust the range as needed
    tooltip=['Ward', 'Postcode', 'count', 'long', 'lat']
).properties(title='Map of vouchers by postcode')

text = alt.Chart(postcode_meals).mark_text(dy=-5).encode(
    longitude='long:Q',
    latitude='lat:Q',
    text='Postcode'
)

shape_data = {'NAME': {555: 'Hoxton East & Shoreditch',
  556: 'Haggerston',
  557: 'De Beauvoir',
  558: 'London Fields',
  559: 'Hackney Wick'},
 'GSS_CODE': {555: 'E05009377',
  556: 'E05009375',
  557: 'E05009371',
  558: 'E05009381',
  559: 'E05009374'},
 'DISTRICT': {555: 'Hackney',
  556: 'Hackney',
  557: 'Hackney',
  558: 'Hackney',
  559: 'Hackney'},
 'LAGSSCODE': {555: 'E09000012',
  556: 'E09000012',
  557: 'E09000012',
  558: 'E09000012',
  559: 'E09000012'},
 'HECTARES': {555: 102.355,
  556: 86.724,
  557: 59.347,
  558: 101.739,
  559: 163.387},
 'NONLD_AREA': {555: 0.0, 556: 0.0, 557: 0.0, 558: 0.0, 559: 0.0},
 'geometry': {555: <POLYGON ((532942.697 -182547.896, 532938.501 -182560.802, 532968.496 -18257...>,
  556: <POLYGON ((534479.503 -183624.697, 534466.698 -183600.304, 534458.098 -18357...>,
  557: <POLYGON ((533479.5 -183988.203, 533451.096 -183988.003, 533450.7 -183978.79...>,
  558: <POLYGON ((533479.5 -183988.203, 533479.5 -184005.498, 533479.698 -184015.39...>,
  559: <POLYGON ((537572.901 -185494.702, 537509.497 -185492.903, 537446.1 -185494....>}}

points = {'Postcode': {0: 'N16 5RF', 1: 'N16 5RF', 2: 'N16 5RF', 3: 'N16 5RF'},
 'Ward': {0: 'Springfield',
  1: 'Springfield',
  2: 'Stamford Hill West',
  3: 'Stamford Hill West'},
 'lat': {0: 51.572046, 1: 51.572046, 2: 51.572046, 3: 51.572046},
 'long': {0: -0.075572, 1: -0.075572, 2: -0.075572, 3: -0.075572},
 'geometry': {0: <POINT (-0.076 51.572)>,
  1: <POINT (-0.076 51.572)>,
  2: <POINT (-0.076 51.572)>,
  3: <POINT (-0.076 51.572)>}}

But when I tried that I get this.

enter image description here

The CRS setting is right but for some reason the inner coords of the boundaries are an several orders of magnitude beyond typical latitude and longitudes.

1

There are 1 best solutions below

0
elksie5000 On

The problem I had was that the data was loaded into a dataframe rather than directly from a file using geopandas.GeoDataframe().

My dataframe was called london_wards_shp and just needed the geometry to be loaded using shapely's wkt method, and knowing it was eastings and northings just needed to be converted to lat longs.

import geopandas as gpd
from shapely import wkt
geometry = london_wards_shp['geometry'].apply(wkt.loads)
london_wards_gdf = gpd.GeoDataFrame(london_wards_shp, geometry=geometry)
london_wards_gdf.crs = "EPSG:27700"
london_wards_gdf = london_wards_gdf.to_crs("EPSG:4326")