Plotting polygons onto folium with a gdf frame error - python

I have an issue i made a fairly simple code I just create my file then create the map and the plot it but I get an error. I want to be plotting the polygons from the file onto the map.
import pandas as pd
import folium
import geopandas as gpd
input_map = "CLUSTERS.TAB"
gdf = gpd.read_file(input_map, driver="MapInfo File")
maploc = folium.Map(location=[42.377157,-71.236088],zoom_start=11,tiles="Stamen Toner")
folium.GeoJson(gdf).add_to(maploc)
The error I get is
builtins.RuntimeError: b'no arguments in initialization list'
I have no idea what this means or how to fix it. Any input helps, Thanks.

Related

Using missing_kwds with geopandas changes the shape of the displayed map

I'm using Geopandas (0.11.1) to plot data on maps. I'm facing an issue with missing_kwds. As some of my values are undefined, I want them to be colored in a specific way. I do that using the missing_kwds option of the plot method.
However, when using it, the shape of the map slightly changes, which is disgraceful when switching quickly from one to the other.
Here is an example.
A map without using missing_kwds :
import geopandas
import matplotlib.pyplot as plt
df = geopandas.read_file(geopandas.datasets.get_path("naturalearth_lowres"))
df.plot()
plt.savefig('world1.png')
A map using missing_kwds :
import geopandas
import matplotlib.pyplot as plt
import numpy as np
df = geopandas.read_file(geopandas.datasets.get_path("naturalearth_lowres"))
df.loc[df.name=="China", 'pop_est'] = np.nan
df.plot(column="pop_est", missing_kwds=dict(color="lightgray"))
plt.savefig('world2.png')
Those are the two resulting maps.
world1.png:
world2.png:
In case the difference isn't clear, here is a GIF that illustrates the shape changes.
Does anyone have an idea how I could solve this issue?
Add plt.gca().set_aspect('equal') after df.plot().

Interactive Xarray dataset raster visualisation app using Panel and hvplot

I am trying to replicate the Glaciers Demo using an Xarray of geospatial data. I am able to create pretty much exactly what I want but I am trying to create a Panel app that allows the user to select the data_vars, each of which has different dimensions that I want make interactable, and visualize on an interactive map with at least the continents contour. Here is what my Xarray Dataset looks like :
def plot(field):
return xds[field].hvplot.image().opts(cmap='jet',height=650,width=1300,data_aspect=1)
interact(plot, field = list(xds.data_vars))
and here is what the code above produces in a notebook :
I would like to integrate the selector for the data_vars and then depending on its dimensions have interactive maps with controls for all its dimensions (ES has (time, pres1, lat, lon) while P0 has only (time, lat, lon)) and I would like to have the controls in the sidebar and the plots in the main of the following template :
from turtle import width
from matplotlib.pyplot import title
import panel as pn
import numpy as np
import holoviews as hv
from panel.template import DefaultTheme
from pathlib import Path
import fstd2nc
import hvplot.xarray
import xarray as xr
from unicodedata import name
import hvplot
import param
from panel.interact import interact
pn.extension(sizing_mode='stretch_width')
bootstrap = pn.template.MaterialTemplate(title='Material Template', theme=DefaultTheme, )
glob_path = Path(r"C:\Users\spart\Documents\Anaconda-Work-Dir")
file_list = [str(pp).split('\\')[-1] for pp in glob_path.glob("2022*")]
phase = pn.widgets.FloatSlider(name="Phase", start=0, end=np.pi)
fileSel = pn.widgets.Select(name='Select File', options=file_list)
#pn.depends(fileSel=fileSel)
def selectedFile(fileSel):
base_path = r"C:\Users\spart\Documents\Anaconda-Work-Dir\{}".format(fileSel)
return pn.widgets.StaticText(name='Selected', value=base_path)
#pn.depends(fileSel=fileSel)
def dataXArray(fileSel):
base_path = r"C:\Users\spart\Documents\Anaconda-Work-Dir\{}".format(fileSel)
xds = fstd2nc.Buffer(base_path).to_xarray()
return xds.ES.hvplot( width=500)
bootstrap.sidebar.append(fileSel)
bootstrap.sidebar.append(selectedFile)
bootstrap.main.append(
pn.Row(
pn.Card(hv.DynamicMap(dataXArray), title='Plot'),
)
)
bootstrap.show()
EDIT : Here is a link to an example dataset which can be loaded with the following code
xds = fstd2nc.Buffer(PATH_TO_FILE).to_xarray()
Without the data file I can't easily run the code, but some observations:
If using bare functions like this rather than classes, I'd recommend using pn.bind rather than pn.depends; it really helps get the code organized better.
For a simple application like this, I'd use hvPlot .interactive: https://hvplot.holoviz.org/user_guide/Interactive.html
I can't seem to find this in the docs, but you can pull out the widgets from the result of dataXArray (or any other hvplot or holoviews object) using .widgets(), and you can then put that in the sidebar. You can then pull out just the plot using .panel(), and put that in the main area.
If that helps you get it done, then great; if not please post a sample data file or two so that it's runnable, and I can look into it further. And please submit a PR to the docs once you get it working so that future users have less trouble!

Contextily add_basemap inferred zoom level is not valid and changing zoom parameter doesn't fix issue

I want to plot the background map of Melbourne behind the plotted points of property addresses.
I used the following code:
import pandas as pd
import geopandas as gpd
from shapely.geometry import shape
import matplotlib.pyplot as plt
import contextily
MELB_PROPERTY_DATA = "https://data.melbourne.vic.gov.au/resource/imwx-szwr.json"
properties = pd.read_json(MELB_PROPERTY_DATA)
properties['the_geom'] = properties['the_geom'].apply(shape)
properties_geo = gpd.GeoDataFrame(properties).set_geometry('the_geom')
ax = properties_geo.plot(markersize=1)
contextily.add_basemap(ax)
plt.show()
At the contextily.add_basemap(ax) line I get the following UserWarning.
contextily\tile.py:632: UserWarning: The inferred zoom level of 30 is
not valid for the current tile provider (valid zooms: 0 - 18).
I read the Contextily docs but they don't fix my problem.
Changing the line to contextily.add_basemap(ax, zoom=5) removes the UserWarning but still no background map appears.
Similar questions have been asked on SO, but I can't retrofit them to my problem.
I feel like I'm importing lots of libraries for this simple task as well, so if you have any suggestions to fine-tune it that would also be appreciated.
I solved this by realising from swatchai's comment that a Coordinate Reference System (CRS) was never defined.
See below for final code, with erroneous lines commented out to show the difference.
import pandas as pd
import geopandas as gpd
from shapely.geometry import shape
import matplotlib.pyplot as plt
import contextily
MELB_PROPERTY_DATA = "https://data.melbourne.vic.gov.au/resource/imwx-szwr.json"
properties = pd.read_json(MELB_PROPERTY_DATA)
properties['the_geom'] = properties['the_geom'].apply(shape)
# properties_geo = gpd.GeoDataFrame(properties).set_geometry('the_geom')
properties_geo = gpd.GeoDataFrame(properties, geometry='the_geom', crs='EPSG:4326')
ax = properties_geo.plot(markersize=1)
# contextily.add_basemap(ax)
contextily.add_basemap(ax, crs=properties_geo.crs.to_string())
plt.show()

.plot() command does not display anything

I have this code based on this question, just a different point Extract constrained polygon using OSMnx
I am trying to plot the block in which the point is located but it does nothing, it just prints "Done" but I cannot see any image
import osmnx as ox
import geopandas as gpd
import shapely
point = (50.090464, 14.400070)
streets_graph = ox.graph_from_point(point, distance=500, network_type='drive')
streets_graph = ox.project_graph(streets_graph)
streets = ox.save_load.graph_to_gdfs(streets_graph, nodes=False, edges=True,
node_geometry=False, fill_edge_geometry=True)
point = streets.unary_union.centroid
polygons = shapely.ops.polygonize(streets.geometry)
polygons = gpd.GeoSeries(polygons)
target = polygons.loc[polygons.contains(point)]
target_streets = streets.loc[streets.intersection(target.iloc[0]).type == 'MultiLineString']
ax = target_streets.plot()
gpd.GeoSeries([point]).plot(ax=ax, color='r')
print("Done")
I do not think this may help but I am using Visual Studio Code
Thank you very much
Since my comment answered your question, I will summarize it here for other people:
When using plotting library dependent on matplotlib, like geopandas or seaborn, you will need to import matplotlib in order to show the plot. The way matplotlib is imported will depend on whether you are using Jupyter or simple scripting (.py) files.
For Jupyter you need to import it like this:
%matplotlib inline
For simple scripting (.py) file you need to import it like this:
import matplotlib.pyplot as plt
Then when you want to show your plot you simply do
plt.show()
Hope it helps!

Find all intersecting polygons in a shape file

I am trying to find out all the polygons in a shapefile through QGIS Algorithm Extract By Location and it gives me perfect results but takes too much time, around 25 hours. Now, I want it to be done by other libraries like geopandas or other libraries if possible. Can anyone suggest me which library can help?
This is what am doing in geopandas:
import itertools
import geopandas as gpd
gi = gpd.GeoDataFrame.from_file("D:\Shape_file_uploader\qgis\laneGroup.shp")
geoms = gi['geometry'].tolist()
intersection_iter = gpd.GeoDataFrame(gpd.GeoSeries([poly[0].intersection(poly[1]) for poly in itertools.combinations(geoms, 2)
I did this some time ago and if I remember correctly I used the geopandas overlay method. So the 'pseudo' code to handle this ...
from geopandas import GeoDataFrame, overlay
first_shape_gdf = GeoDataFrame.from_file('D:\Shape_file_uploader\qgis\laneGroup.shp')
second_shape_gdf = GeoDataFrame.from_file('another.shp')
intersection_gdf = overlay(first_shape_gdf, second_shape_gdf, how='intersection')
Have a look at Set-Operations with Overlay

Categories