{ "nbformat": 4, "nbformat_minor": 0, "metadata": { "colab": { "name": "MakeABasicMap.ipynb", "version": "0.3.2", "provenance": [], "collapsed_sections": [], "include_colab_link": true }, "kernelspec": { "name": "python3", "display_name": "Python 3" } }, "cells": [ { "cell_type": "markdown", "metadata": { "id": "view-in-github", "colab_type": "text" }, "source": [ "\"Open" ] }, { "cell_type": "markdown", "metadata": { "id": "dfXStwLAk9GC", "colab_type": "text" }, "source": [ "Get the tools we need! We will always start like this." ] }, { "cell_type": "code", "metadata": { "id": "ws-jEcyKk0MF", "colab_type": "code", "outputId": "cae2659f-f189-48a6-803c-87487a226b2e", "colab": { "base_uri": "https://localhost:8080/", "height": 51 } }, "source": [ "import folium\n", "import branca\n", "import pandas as pd\n", "print(folium.__file__)\n", "print(folium.__version__)" ], "execution_count": 1, "outputs": [ { "output_type": "stream", "text": [ "/usr/local/lib/python3.6/dist-packages/folium/__init__.py\n", "0.8.3\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "ZnRemIE7mUQK", "colab_type": "text" }, "source": [ "Get some data. \n", "\n", "We'll experiment with the data from:\n", "\n", " Palmisano, A., Bevan, A. and Shennan, S., 2018. Regional Demographic Trends and Settlement Patterns in Central Italy: Archaeological Sites and Radiocarbon Dates. Journal of Open Archaeology Data, 6(1), p.2. DOI: http://doi.org/10.5334/joad.43\n", " \n", " These nice people provided the data behind their analysis so we can re-use it." ] }, { "cell_type": "code", "metadata": { "id": "F0B_wkOblGUW", "colab_type": "code", "outputId": "f61ddf82-ffaf-4deb-c91b-d445906bb916", "colab": { "base_uri": "https://localhost:8080/", "height": 340 } }, "source": [ "palmisano_tuscany_sites = pd.read_csv(\"https://raw.githubusercontent.com/ropitz/spatialarchaeology/master/data/site_centriods_tuscany.txt\")\n", "\n", "palmisano_tuscany_sites.head()" ], "execution_count": 2, "outputs": [ { "output_type": "execute_result", "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
OBJECTIDIdToponymsTypePeriodStartDateEndDateLongitudeLatitudeLocQualSizeHaSizeQualSourceSource_idORIG_FID
011PadiglionesettlementIron Age-800-70012.63932441.515316A0.2EAttema et al. 2010, p. 229151140
121PadiglionesettlementRepublican Period-100-3012.63681741.516111A0.2EAttema et al. 2010, p. 229151141
231PadiglionesettlementImperial Period-3040012.63679341.516111A0.2EAttema et al. 2010, p. 229151142
341PadiglionesettlementLate Antique/Early Medieval40050012.63681741.516111A0.2EAttema et al. 2010, p. 229151143
452AsturasettlementIron Age-700-60012.76931341.417720A34.0DAttema et al. 2010, p. 186; Picarreta 1977, p.21112014
\n", "
" ], "text/plain": [ " OBJECTID Id ... Source_id ORIG_FID\n", "0 1 1 ... 15114 0\n", "1 2 1 ... 15114 1\n", "2 3 1 ... 15114 2\n", "3 4 1 ... 15114 3\n", "4 5 2 ... 11201 4\n", "\n", "[5 rows x 15 columns]" ] }, "metadata": { "tags": [] }, "execution_count": 2 } ] }, { "cell_type": "markdown", "metadata": { "id": "14eCo5OlnD6b", "colab_type": "text" }, "source": [ "Let's say your question is about how many iron age sites are present in the region, and what their distribution is like in space - that is where they are located and how many relatively speaking are in each area. Filter your big data file to get just the iron age sites.\n" ] }, { "cell_type": "code", "metadata": { "id": "1PiNejEBmrhR", "colab_type": "code", "outputId": "df39885e-10e1-46cc-af3b-eed032baece3", "colab": { "base_uri": "https://localhost:8080/", "height": 306 } }, "source": [ "palmisano_tuscany_sites_iron_age = palmisano_tuscany_sites[(palmisano_tuscany_sites['Period']==\"Iron Age\") ]\n", "\n", "palmisano_tuscany_sites_iron_age.head()" ], "execution_count": 3, "outputs": [ { "output_type": "execute_result", "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
OBJECTIDIdToponymsTypePeriodStartDateEndDateLongitudeLatitudeLocQualSizeHaSizeQualSourceSource_idORIG_FID
011PadiglionesettlementIron Age-800-70012.63932441.515316A0.20EAttema et al. 2010, p. 229151140
452AsturasettlementIron Age-700-60012.76931341.417720A34.00DAttema et al. 2010, p. 186; Picarreta 1977, p.21112014
969765Piscina della FarnasettlementIron Age-700-60012.72617341.482471A0.04EAttema et al. 20101128496
10410570CadolinosettlementIron Age-800-70012.66256641.492596A1.00EAttema et al. 201015003104
13313481Pineta della CampanasettlementIron Age-700-60012.67064441.513748A0.08EAttema et al. 201015029133
\n", "
" ], "text/plain": [ " OBJECTID Id ... Source_id ORIG_FID\n", "0 1 1 ... 15114 0\n", "4 5 2 ... 11201 4\n", "96 97 65 ... 11284 96\n", "104 105 70 ... 15003 104\n", "133 134 81 ... 15029 133\n", "\n", "[5 rows x 15 columns]" ] }, "metadata": { "tags": [] }, "execution_count": 3 } ] }, { "cell_type": "markdown", "metadata": { "id": "lTRfAfasnd1A", "colab_type": "text" }, "source": [ "Now we want to add this data to a simple map. You need to start by getting the coordiantes so you can center the map - that is focus on the area where your data is. You want to add a marker for each site. \n", "\n" ] }, { "cell_type": "code", "metadata": { "id": "DhHMGaQMneNF", "colab_type": "code", "colab": { "base_uri": "https://localhost:8080/", "height": 750 }, "outputId": "2398b466-3057-4914-f7c2-08671bfdd6b5" }, "source": [ "#location is the mean of every lat and long point to centre the map.\n", "location = palmisano_tuscany_sites_iron_age['Latitude'].mean(), palmisano_tuscany_sites_iron_age['Longitude'].mean()\n", "\n", "#A basemap is then created using the location to centre on and the zoom level to start.\n", "m = folium.Map(location=location,zoom_start=10)\n", "\n", "#Each location in the DataFrame is then added as a marker to the basemap points are then added to the map\n", "for i in range(0,len(palmisano_tuscany_sites_iron_age)):\n", " folium.Marker([palmisano_tuscany_sites_iron_age['Latitude'].iloc[i],palmisano_tuscany_sites_iron_age['Longitude'].iloc[i]]).add_to(m)\n", " \n", "m" ], "execution_count": 9, "outputs": [ { "output_type": "execute_result", "data": { "text/html": [ "
" ], "text/plain": [ "" ] }, "metadata": { "tags": [] }, "execution_count": 9 } ] }, { "cell_type": "markdown", "metadata": { "id": "xT89bOyooeE9", "colab_type": "text" }, "source": [ "Yay! You have a map. Now, a design question: what is a good starting zoom level. Do you want your map zoomed further out or further in given the extent of your data. In the cell above, play around with the 'zoom_start' parameter and find a good zoom level." ] }, { "cell_type": "markdown", "metadata": { "id": "T6kjhm_lpmEu", "colab_type": "text" }, "source": [ "Now let's look at how to represent larger and smaller sites. The archaeologists in this project have a qualitative ranking of site size from large (A) to small (F). You can see the categories they've used, and that there are more small sites than larger ones. Say you want to make the two categories of sites that are the largest different colours." ] }, { "cell_type": "code", "metadata": { "id": "-x3bmE-3ov3c", "colab_type": "code", "colab": { "base_uri": "https://localhost:8080/", "height": 119 }, "outputId": "278c6115-5ec5-4b8f-837d-63625031c255" }, "source": [ "#Size surely matters... get the number of sites in each site category. \n", "palmisano_tuscany_sites_iron_age['SizeQual'].value_counts()" ], "execution_count": 10, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "F 82\n", "E 80\n", "D 74\n", "B 60\n", "C 24\n", "Name: SizeQual, dtype: int64" ] }, "metadata": { "tags": [] }, "execution_count": 10 } ] }, { "cell_type": "code", "metadata": { "id": "_vu_cUOzp77n", "colab_type": "code", "colab": { "base_uri": "https://localhost:8080/", "height": 750 }, "outputId": "e0bca3d3-c061-414b-ce83-c4e9cfdf8276" }, "source": [ "#now make a map just like you did before. Note that this time we're adding a scale bar with 'control_scale'\n", "location = palmisano_tuscany_sites_iron_age['Latitude'].mean(), palmisano_tuscany_sites_iron_age['Longitude'].mean()\n", "m = folium.Map(location=location,zoom_start=10,control_scale = True)\n", "\n", "#Assign different colours to the two large site categories - B and C in this case\n", "for i in range(0,len(palmisano_tuscany_sites_iron_age)):\n", "\n", "\n", " site_size = palmisano_tuscany_sites_iron_age['SizeQual'].iloc[i]\n", " if site_size == 'C':\n", " color = 'blue'\n", " elif site_size == 'B':\n", " color = 'green'\n", " else:\n", " color = 'red'\n", " \n", " \n", " folium.Marker([palmisano_tuscany_sites_iron_age['Latitude'].iloc[i],palmisano_tuscany_sites_iron_age['Longitude'].iloc[i]],icon=folium.Icon(color=color)).add_to(m)\n", "\n", "m" ], "execution_count": 15, "outputs": [ { "output_type": "execute_result", "data": { "text/html": [ "
" ], "text/plain": [ "" ] }, "metadata": { "tags": [] }, "execution_count": 15 } ] }, { "cell_type": "markdown", "metadata": { "id": "VjuGVxl8rKue", "colab_type": "text" }, "source": [ "Now, go back into the cell above and experiment a bit. Try out some different colours. Do certain combinations work well? Try adding different colours for each of the smaller categories of sites. Does that make the map clearer or more confusing?" ] }, { "cell_type": "markdown", "metadata": { "id": "ZcN5jSj13Ive", "colab_type": "text" }, "source": [ "Maybe it makes more sense to show size by changing the size of the icon than the colour. Let's make another map that varies the size of the icon for each site based on its size in hectares." ] }, { "cell_type": "code", "metadata": { "id": "8d_u8uL5wKBg", "colab_type": "code", "colab": { "base_uri": "https://localhost:8080/", "height": 750 }, "outputId": "e147d61c-be18-4627-ebf8-a943ddba0f06" }, "source": [ "#now make a map just like you did before. \n", "location = palmisano_tuscany_sites_iron_age['Latitude'].mean(), palmisano_tuscany_sites_iron_age['Longitude'].mean()\n", "m = folium.Map(location=location,zoom_start=8,control_scale = True)\n", "\n", "\n", "# Set the size for each circle icon by defining the 'radius' which is the radius of the circle\n", "# Here we are multiplying the size in hectares (SizeHa) by 15. Try different values here to get icons a size you like\n", "for i in range(0,len(palmisano_tuscany_sites_iron_age)):\n", " folium.Circle(\n", " location=[palmisano_tuscany_sites_iron_age['Latitude'].iloc[i],palmisano_tuscany_sites_iron_age['Longitude'].iloc[i]],\n", " popup=palmisano_tuscany_sites_iron_age.iloc[i]['Toponyms'],\n", " radius=palmisano_tuscany_sites_iron_age.iloc[i]['SizeHa']*15,\n", " color='crimson',\n", " fill=True,\n", " fill_color='crimson'\n", " ).add_to(m)\n", " \n", "m" ], "execution_count": 31, "outputs": [ { "output_type": "execute_result", "data": { "text/html": [ "
" ], "text/plain": [ "" ] }, "metadata": { "tags": [] }, "execution_count": 31 } ] }, { "cell_type": "markdown", "metadata": { "id": "UGrxvlO1sn1m", "colab_type": "text" }, "source": [ "Now what if you want to make a map that shows the concentration of sites in the iron age, that is areas with many and fewer sites? \n", "\n", "\n", "This kind of map is often called a 'heatmap'. Essentially it shows areas with more sites as 'hotter' (generally red in colour) and areas with fewer sites as cooler.\n", "\n", "\n", "In this kind of map surely larger sites should count more - we call this 'weighting'. The general idea is that a site that is twice as large should count for twice as much in our heatmap.\n" ] }, { "cell_type": "code", "metadata": { "id": "dMDhTabesLOc", "colab_type": "code", "colab": {} }, "source": [ "#first make a list of the coordinates of each site and its size in hectares, which we will use for the size-based weighting\n", "data_heat = palmisano_tuscany_sites_iron_age[['Latitude','Longitude','SizeHa']].values.tolist()" ], "execution_count": 0, "outputs": [] }, { "cell_type": "code", "metadata": { "id": "pzzi69aXtyMN", "colab_type": "code", "colab": { "base_uri": "https://localhost:8080/", "height": 34 }, "outputId": "ae855149-c38d-465e-eef7-42e7369f1bd7" }, "source": [ "#look at the first line of your list to check it seems to have worked\n", "data_heat[0]" ], "execution_count": 17, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "[41.51531639941, 12.63932357767, 0.2]" ] }, "metadata": { "tags": [] }, "execution_count": 17 } ] }, { "cell_type": "code", "metadata": { "id": "TVAorbp9uKIS", "colab_type": "code", "colab": {} }, "source": [ "#to make the heatmap, we need to get an extra tool, so...\n", "import folium.plugins as plugins\n", "\n" ], "execution_count": 0, "outputs": [] }, { "cell_type": "code", "metadata": { "id": "ZIe4sfeVuM80", "colab_type": "code", "colab": { "base_uri": "https://localhost:8080/", "height": 750 }, "outputId": "5251fd41-047c-4782-9f02-2d10a9bfd917" }, "source": [ "# now make a map a bit like you did before, set your zoom level and your centre location. Then use the plugin to make the heatmap. \n", "\n", "m = folium.Map(location=location, zoom_start=10)\n", "#tiles='stamentoner'\n", "\n", "plugins.HeatMap(data_heat).add_to(m)\n", "\n", "m" ], "execution_count": 20, "outputs": [ { "output_type": "execute_result", "data": { "text/html": [ "
" ], "text/plain": [ "" ] }, "metadata": { "tags": [] }, "execution_count": 20 } ] } ] }