You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
For a project, I want to plot the intersection between the Earth and specific planes facing the Sun. For this, I use the Nightshade feature : I take advantage of the refraction parameter to adjusts the day/night geometry boundary, which has the same result as shifting a plane facing the Sun. I use stereographic projection, so all the resulting projected polygons are discs or circular holes.
However, the behavior of the feature is inconsistent when the refraction value is positive (normally the value is zero or negative), especially at dates close to summer solstices (but not always at the exact solstice). The definition of the inside/outside of the polygon seems randomly wrong, as if the points weren't ordered correctly.
These are pretty extreme values for the refraction but it may underline an issue with the source code. As a suggestion, since the Nightshade feature compute the solar position lat, lon = _solar_position(date)
it should be possible to determine the correct orientation as the projected polygon (representing the shaded part of the Earth) should be the one not containing this point.
Code to reproduce
from datetime import datetime
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
from cartopy.feature.nightshade import Nightshade
date = datetime(2024, 6, 11)
strdate = date.strftime("%d/%m/%Y, %H:%M")
proj = ccrs.Stereographic(90., 0.0)
fig, axs = plt.subplots(3, 4, figsize=(12 , 9), subplot_kw={'projection': proj})
for i, ax in enumerate(axs.flatten()):
nightshade = Nightshade(date, refraction= i)
ax.add_feature(nightshade)
ax.coastlines()
ax.set_global()
ax.set_title(f"Refraction={i}")
fig.suptitle(f'{strdate}', fontsize = 20.)
plt.show()
Thanks for the clear report @Eliam76. Everything seems fine if we plot in the projection in which Nightshade is defined, so it looks like this is an instance of problems in the transforms.
Thank you for your answer. Yes it seems that there are many projections in which the Nightshade feature behaves correctly. I tried to "manually" project the geometry using the following modification of the loop :
for i, ax in enumerate(axs.flatten()):
nightshade = Nightshade(date, refraction= i)
# Extract feature geom in the native projection
ns_geom = next(nightshade.geometries())
# Project geometry in axe crs
proj_ns_geom = ax.projection.project_geometry(ns_geom, nightshade.crs)
print(proj_ns_geom.area)
# Create feature from projected geometry
proj_ns_feat = ShapelyFeature(proj_ns_geom, crs=proj)
ax.add_feature(proj_ns_feat)
ax.coastlines()
ax.set_global()
ax.set_title(f"Refraction={i}")
which gives the same result as in my initial post
The output from the print(proj_ns_geom.area) line confirms that the issue occurs in the project_geometry function since there are very significant reductions/increases in proj_ns_geom area before the creation of the ShapelyFeature (the expected behavior would be for the evolution of surface area to be a monotonic function)
5151773704494255.0
5246243033890791.0
5344798516527959.0
5448653067659229.0
5559983616304591.0
5684227535698096.0
2013242591740023.2 <- should be greater than the previous area
1872608307796799.8
1744912668814188.0
1628637143988004.0
6325209799254183.0
1425090085522831.8
Looking at the Projection class (#L954) it seems indeed that it may be the origin of the issue according to this comment
# Determine orientation of polygon.
# TODO: Consider checking the internal rings have the opposite
# orientation to the external rings?
if src_crs.is_geodetic():
is_ccw = True
else:
is_ccw = polygon.exterior.is_ccw
Description
For a project, I want to plot the intersection between the Earth and specific planes facing the Sun. For this, I use the Nightshade feature : I take advantage of the refraction parameter to adjusts the day/night geometry boundary, which has the same result as shifting a plane facing the Sun. I use stereographic projection, so all the resulting projected polygons are discs or circular holes.
However, the behavior of the feature is inconsistent when the refraction value is positive (normally the value is zero or negative), especially at dates close to summer solstices (but not always at the exact solstice). The definition of the inside/outside of the polygon seems randomly wrong, as if the points weren't ordered correctly.
These are pretty extreme values for the refraction but it may underline an issue with the source code. As a suggestion, since the Nightshade feature compute the solar position
lat, lon = _solar_position(date)
it should be possible to determine the correct orientation as the projected polygon (representing the shaded part of the Earth) should be the one not containing this point.
Code to reproduce
Full environment definition
Operating system
Windows 10 Family, 64bits edition
Cartopy version
0.23.0
pip list
py -3.12 -m pip list
The text was updated successfully, but these errors were encountered: