6

Starting with a shapefile I obtained from https://s3.amazonaws.com/nyc-tlc/misc/taxi_zones.zip, I'd like to plot the borough of Manhattan, and have outlines for each taxi-zone.

This code rotates each individual taxi zone individually instead of all at once.

import geopandas as gpd
from matplotlib import pyplot as plt


fname = "path_to_shapefile.shp"
df = gpd.read_file(fname)
df = df[df['borough'] == "Manhattan"]
glist = gpd.GeoSeries([g for g in df['geometry']])
glist = glist.rotate(90)
glist.plot()

enter image description here

[EDIT] I have further refined this to be able to rotate the image programmatically. However, if I add a legend, then that is also rotated, which is not desirable. Still looking for a better solution. Note, there is also this stackoverflow post (How can I rotate a matplotlib plot through 90 degrees?), however, the solutions that rotate the plot, and not the image, only work with 90 degree rotations.

import geopandas as gpd
from matplotlib import pyplot as plt

import numpy as np
from scipy import ndimage
from matplotlib import transforms


fname = "path_to_shapefile.shp"
df = gpd.read_file(fname)
df = df[df['borough'] == "Manhattan"]
df.plot()
plt.axis("off")
plt.savefig("test.png")

img = plt.imread('test.png')

rotated_img = ndimage.rotate(img, -65)
plt.imshow(rotated_img, cmap=plt.cm.gray)
plt.axis('off')
plt.show()

[EDIT2]

A simple modification to the answer given below by @PMende solved it.

df = gpd.read_file(fname)
df = df[df['borough'] == "Manhattan"]
glist = gpd.GeoSeries([g for g in df['geometry']])
glist = glist.rotate(-65, origin=(0,0))
glist.plot()

The key was rotating all of the objects around a single point, instead of around their individual origins.

[EDIT 3] If anyone is trying to do this, and needs to save the resulting rotated geoseries to a dataframe (say for instance, to color the geometry based on an additional column), you need to create a new one, simply writing

df['geometry'] = glist

does not work. I'm not sure why at the moment. However, the following code worked for me.

new_dataframe = gpd.GeoDataFrame(glist)
new_dataframe = new_dataframe.rename(columns={0:'geometry'}).set_geometry('geometry')
new_dataframe.plot()

enter image description here

3
  • 4
    Remember that you probably don't want to rotate your geometry as it would lose its geographical meaning. You want to rotate matplotlib plot only. That might help googling. Commented Dec 27, 2019 at 15:40
  • @martinfleis thank you for your suggestion -- that did help. I found a way to rotate the entire image, but if I add a legend, that would also be rotated, which is a problem. Commented Jan 13, 2020 at 17:09
  • 1
    I know this is an old question, but is there a way to add a basemap (e.g., using Contextily)? I had a similar question here: stackoverflow.com/questions/65498106/… Commented Jan 4, 2021 at 18:34

1 Answer 1

4

If I'm understanding GeoPandas' documentation correctly, you can specify the origin of the rotation of each of your geometries (which by default is the center of each geometry). To get your desired behavior, you can rotate each shape about the same origin.

For example:

import geopandas as gpd
from matplotlib import pyplot as plt


fname = "path_to_shapefile.shp"
df = gpd.read_file(fname)
df = df[df['borough'] == "Manhattan"]

center = df["geometry"].iloc[0].centroid()
glist = gpd.GeoSeries([g for g in df['geometry']])
glist = glist.rotate(90, origin=center)

glist.plot()

I can't test this myself, but it should hopefully get you started in the right direction.

(Though I also agree with @martinfeleis' point about not necessarily wanting to rotate the geometry, but rather the plot.)

Sign up to request clarification or add additional context in comments.

2 Comments

You don't even need to get the center -- you can actually just make the origin (0,0) the point to rotate around and it works. Thank you for your help!
I know this is an old question, but is there a way to add a basemap (e.g., using Contextily)? I had a similar question here: stackoverflow.com/questions/65498106/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.