I'm trying to plot a state of Germany with geopandas. Unfortunately the plot is a bit streched.
import matplotlib.pyplot as plt
import geopandas as gpd
shapes = gpd.read_file('shapes.shp')
shapes.plot(figsize=(20,20), color='white', edgecolor='black')
If I execute the code above, I'll receive the following plot.
But if you compare the shape of the plot to the real shape of the state as displayed below, then this plot is a bit streched.
I tried to adjust the axes and the figsize, but I didn't work.
Thanks for your help
As gboffi mentioned the projection is not right. So i changed it to EPSG:3857.
import matplotlib.pyplot as plt
import geopandas as gpd
shapes = gpd.read_file('shapes.shp').to_crs(epsg=3857)
fig, axs = plt.subplots(1, 1, figsize=(15,15))
shapes.plot(ax=axs, color='white', edgecolor='black')
Related
I made a figure of three subplots with different size, but I don't know how to change the left one to lat-lon projection provided by cartopy. I want only the left subplot to have the property of projection : ccrs.PlateCarree() or transform = ccrs.PlateCarree() so that I can plot a map on it, while the other two subplots on the right should remain unchanged. Can someone tell me where I should put the projection information?
Here is my code so far:
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
proj = ccrs.PlateCarree(central_longitude=0)
fig, axes = plt.subplot_mosaic("AABB;AABB;AACC", figsize = (16, 6))
plt.show()
All comments are welcome. Thanks in advance.
I don't think it's possible with the higher level methods like subplots or subplot_mosaic. But when you use the GridSpec method, you can provide axes-specific keywords.
For example:
import matplotlib.pyplot as plt
from matplotlib.gridspec import GridSpec
import cartopy.crs as ccrs
import numpy as np
fig = plt.figure(figsize=(9, 3), constrained_layout=True, facecolor="w")
gs = GridSpec(3, 3, figure=fig)
ax1 = fig.add_subplot(gs[:, 0], projection=ccrs.PlateCarree())
ax2 = fig.add_subplot(gs[0:2, 1])
ax3 = fig.add_subplot(gs[2:3, 1])
ax1.set_extent((-90,90,90,-90))
ax1.coastlines()
ax2.imshow(np.random.rand(10,17))
ax3.plot(np.random.randn(100).cumsum())
https://matplotlib.org/stable/tutorials/intermediate/arranging_axes.html
I found this tutorial on how to do a watermark but I cannot figure out how to put it behind my plotted data.
https://www.tutorialspoint.com/how-to-plot-a-watermark-image-in-matplotlib
Changing zorder has no impact because I think it is being drawn on the entire figure. I would like to have a subdued logo behind my data which is always centered in the figure so I don't really want to plot an image as a data point because then it would move as it is panned/zoomed.
Setting the zorder to a negative value works for me. However, you also need to make the facecolor of the axes transparent:
import numpy as np
import matplotlib.cbook as cbook
import matplotlib.image as image
import matplotlib.pyplot as plt
with cbook.get_sample_data('logo2.png') as file:
im = image.imread(file)
fig, ax = plt.subplots()
fig.figimage(im, 10, 10, zorder=-1, alpha=.5)
ax.plot(np.sin(10 * np.linspace(0, 1)), '-o', ms=20,
alpha=0.7, mfc='orange')
ax.set_facecolor('none')
plt.show()
If I have the plot below, how can I turn the colormap/legend into a log-scale?
import geopandas as gpd
import matplotlib.pyplot as plt
world = gpd.read_file(gpd.datasets.get_path('naturalearth_lowres'))
world = world[(world.pop_est>0) & (world.name!="Antarctica")]
fig, ax = plt.subplots(1, 1)
world.plot(column='pop_est', ax=ax, legend=True)
GeoPandas plots are using matplotlib, so you can use normalization of colormap provided by it. Note than I am also specifying min and max values as mins and maxs of the column I am plotting.
world.plot(column='pop_est', legend=True, norm=matplotlib.colors.LogNorm(vmin=world.pop_est.min(), vmax=world.pop_est.max()), )
You can simply plot the log of the value instead of the value itself.
import geopandas as gpd
import matplotlib.pyplot as plt
from numpy import log10
world = gpd.read_file(gpd.datasets.get_path('naturalearth_lowres'))
world = world[(world.pop_est>0) & (world.name!="Antarctica")]
world['logval'] = log10(world['pop_est'])
fig, ax = plt.subplots(1, 1)
world.plot(column='logval', ax=ax, legend=True)
I am trying to plot points in a shapefile using geopandas and I keep encountering
TypeError: You must first set_array for mappable
whenever I run the code below. This error disappears when I remove the colormap attribute. But I want to change the color of my points and I think colormap is helpful for that.
Here's my code:
import matplotlib.pyplot as plt
import geopandas
shapefile = geopandas.GeoDataFrame.from_file('file.shp')
fig, ax = plt.subplots(1)
base = shapefile.plot(ax=ax)
df.plot.scatter('Long', 'Lat', c=df['colC'], s=df['colD'], alpha=0.7, ax=base, colormap='viridis')
You might try direct calls to matplotlib. I don't have your dataset to try this with, but try the following:
from operator import itemgetter
import geopandas
import matplotlib.pyplot as plt
shapefile = geopandas.GeoDataFrame.from_file('file.shp')
fig, ax = plt.subplots()
shapefile.plot(ax=ax)
x, y, c, s = itemgetter('Long', 'Lat', 'colC', 'colD')(df)
ax.scatter(x, y, c=c, s=s, cmap='viridis')
I have a 2D matrix I want to plot. The plotting itself works, but I need
a colorbar with it. The figure only makes sense when the data is
log-tranformed. And I want the colorbar show the original values. How
do I do this?
A search provided
A logarithmic colorbar in matplotlib scatter plot
but I cannot make this work.
The code below gives an idea of what I attempt to do. Only the revevant
lines are included (as far as I could see).
import matplotlib.pyplot as plt
from matplotlib import cm
import numpy as np
my_speed=np.ones(shape=(no,no))
fig=plt.figure(2)
ax=fig.add_subplot(1,1,1)
my_speed=np.log10(my_speed)
ax.imshow(my_speed, interpolation='bilinear', cmap=cm.jet)
plt.colorbar() #this does not work
plt.savefig('myspeedplot.png')
plt.close(2)
Thank you for any help
The idea is not to transform your data, but let the visualization do the trick for you.
pylot.imshow[1] has an optional parameter norm that can do the log transformation for you.
my_speed=np.ones(shape=(no,no))
fig = plt.figure(2)
ax = fig.add_subplot(1,1,1)
# my_speed=np.log10(my_speed)
img = ax.imshow(my_speed, interpolation='bilinear', cmap=cm.jet,
norm=mpl.colors.LogNorm())
fig.colorbar(img)
As far as I see, there are two problems with your code.
First, you are trying to have the ticks on colorbar show original values. For this you should not transform the data, but just normalize the plot.
And second, you are using the ax.imshow and this is why the colorbar does not see it. You should use plt.imshow or use im=ax.imshow and then colorbar(im)
Here is a working solution:
import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
my_speed = np.random.rand(20, 20)
fig = plt.figure(2)
ax = fig.add_subplot(1, 1, 1)
im = ax.imshow(my_speed, interpolation='bilinear',
norm=mpl.colors.LogNorm(),
cmap=plt.cm.jet)
cb = plt.colorbar(im, orientation='vertical')
plt.show()