Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Geographic Filled KDE Plot #3694

Open
bschweigert opened this issue May 10, 2024 · 4 comments
Open

Geographic Filled KDE Plot #3694

bschweigert opened this issue May 10, 2024 · 4 comments

Comments

@bschweigert
Copy link

I am plotting lat/lon points on a geographic map, and I would like to underlay a KDE plot beneath scatter points. Because they are lat/lon points, the plotting will use a cartopy transform (in my case PlateCarree). When calling the kdeplot function with fill=False, everything works fine. However, with fill = True it returns the error:

AttributeError: 'PlateCarree' object has no attribute 'contains_branch_seperately'

Here is reproducible code:

import numpy as np
import seaborn as sns
import cartopy.crs as ccrs
import matplotlib.pyplot as plt
import cartopy.feature as cfeature

##Create example lat/lon points
lons = np.random.uniform(low = -100, high = -90, size = 20)
lats = np.random.uniform(low = 30, high = 40, size = 20)

##Create the figure
fig = plt.figure(figsize = (6, 4), dpi = 300)
ax = fig.add_subplot(1, 1, 1, projection = ccrs.LambertConformal())

##Add features
ax.add_feature(cfeature.STATES.with_scale('50m'), zorder = 1)
ax.set_extent((-103, -88, 22.5, 42))

##Scatter plot the lat/lon points
ax.scatter(lons, lats, c = 'black', marker = 'x', transform = ccrs.PlateCarree(), zorder = 2)

##Add a KDE underlay
kde = sns.kdeplot(x = lons, y = lats, fill = True, transform = ccrs.PlateCarree(), zorder = 1)

@mwaskom
Copy link
Owner

mwaskom commented May 11, 2024

hm this smells like something between matplotlib and cartopy, that's not a function seaborn is calling directly. can you share the full traceback?

@bschweigert
Copy link
Author

Here is the full traceback:

File ~\Miniconda3\envs\figs\Lib\site-packages\spyder_kernels\py3compat.py:356 in compat_exec
exec(code, globals, locals)

File c:\users\bschweigert2\desktop\lm clim\error_ex.py:28
kde = sns.kdeplot(x = lons, y = lats, fill = True, transform = ccrs.PlateCarree(), zorder = 1)

File ~\Miniconda3\envs\figs\Lib\site-packages\seaborn\distributions.py:1682 in kdeplot
color = _default_color(method, hue, color, kwargs)

File ~\Miniconda3\envs\figs\Lib\site-packages\seaborn\utils.py:136 in _default_color
scout = method([], [], **kws)

File ~\Miniconda3\envs\figs\Lib\site-packages\matplotlib_init_.py:1478 in inner
return func(ax, *map(sanitize_sequence, args), **kwargs)

File ~\Miniconda3\envs\figs\Lib\site-packages\matplotlib\axes_axes.py:5509 in fill_between
return self._fill_between_x_or_y(

File ~\Miniconda3\envs\figs\Lib\site-packages\matplotlib\axes_axes.py:5500 in _fill_between_x_or_y
up_x, up_y = kwargs["transform"].contains_branch_seperately(self.transData)

AttributeError: 'PlateCarree' object has no attribute 'contains_branch_seperately'

That would be intriguing, because I have done plenty of plotting recently with matplotlib and cartopy with no issues thus far. Thanks for the help!

@mwaskom
Copy link
Owner

mwaskom commented May 12, 2024

Based on that it seems like you could reproduce this with something like

f, ax = plt.subplots()
ax.fill_between([], [], transform=ccrs.PlateCarree())

(untested as I don't have the relevant geographic dependencies)

@mwaskom
Copy link
Owner

mwaskom commented May 12, 2024

You may need to set up the subplot with the same projection too, I am not sure.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants