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

Introduced area-based contours #7444

Draft
wants to merge 7 commits into
base: main
Choose a base branch
from
Draft

Conversation

Paras20222
Copy link

@Paras20222 Paras20222 commented Feb 11, 2024

PR Description

This PR introduces area-based contour calculations to enhance visualization accuracy. The changes address issue #7420 and provide a more intuitive method for determining contour levels. This improvement enables better data interpretation in X-ray and radio imaging applications.

@Paras20222 Paras20222 requested a review from a team as a code owner February 11, 2024 15:10
@nabobalis
Copy link
Contributor

Thank you for the PR @Paras20222. I will do a quick review now.

@nabobalis nabobalis added the map Affects the map submodule label Feb 11, 2024
@nabobalis nabobalis marked this pull request as draft February 11, 2024 17:58

def _calculate_contour_levels_by_area(self, levels):
"""
Calculate contour levels based on area containment.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure the word containment is correct here.

sunpy/map/mapbase.py Outdated Show resolved Hide resolved
sunpy/map/mapbase.py Outdated Show resolved Hide resolved
Comment on lines 2318 to 2322
>>> map_data = np.random.rand(100, 100)
>>> quantiles = [0.1, 0.3, 0.5, 0.7, 0.9]
>>> contour_levels = self._calculate_contour_levels_by_area(quantiles)
>>> print(contour_levels)
[0.3160296 0.54729944 0.70897832 0.83778233 0.95295992]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the imports are missing?

Also the print is not needed here. The doctest will print out the return if you do not assign it to a variable.

sunpy/map/mapbase.py Show resolved Hide resolved
@@ -2305,7 +2348,9 @@ def _process_levels_arg(self, levels):
"it should be an Astropy Quantity object.")

if levels.unit == u.percent:
return 0.01 * levels.to_value('percent') * np.nanmax(self.data)
# Calculate contour levels based on area containment
contour_levels = self._calculate_contour_levels_by_area(levels)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can't change the default behavior of this method.

I think for now, adding a "method" keyword (to the draw contours method) that allows you to select this new method would be better.

@@ -2290,6 +2290,49 @@ def draw_quadrangle(self, bottom_left, *, width: (u.deg, u.pix) = None, height:
quad = Quadrangle(anchor, width, height, **kwergs)
axes.add_patch(quad)
return quad

def _calculate_contour_levels_by_area(self, levels):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will also need to be tested both as a normal unit test but also as a figure test. See https://docs.sunpy.org/en/latest/dev_guide/contents/tests.html for more details.

Paras20222 and others added 6 commits February 12, 2024 19:09
Co-authored-by: Nabil Freij <nabil.freij@gmail.com>
Co-authored-by: Nabil Freij <nabil.freij@gmail.com>
@nabobalis
Copy link
Contributor

nabobalis commented Mar 20, 2024

Hi @Paras20222, will you have some time soon to address the outstanding comments?

@AquarlisPrime
Copy link

Hello, i have made few changes to the gist.
`import numpy as np
import matplotlib.pyplot as plt

def area_contour_image(img: np.ndarray, quantiles: list[float], ax=None, x=None, y=None, cmap='Reds', **contour_kwds):

# Normalizing img data
normalized_img = (img - np.min(img)) / np.ptp(img)

# Flatten img data
flattened_img = normalized_img.ravel()

# Sort pixels: small areas first, large areas later
sorted_values = np.sort(flattened_img)[::-1]

# Computing cumi sum
cumulative_sum = np.cumsum(sorted_values) / np.sum(sorted_values)

# Indices corresponding to specified quantiles
indices = np.searchsorted(cumulative_sum, quantiles)

# Threshold values for desired percentile and for drawing contours
thresholds = np.sort(sorted_values[indices])

if ax is None:
    fig, ax = plt.subplots()
if x is None or y is None:
    return ax.contour(normalized_img, levels=thresholds, cmap=cmap, **contour_kwds)
else:
    return ax.contour(x, y, normalized_img, levels=thresholds, cmap=cmap, **contour_kwds)

def test():
x = np.linspace(-10, 10, num=1000)
y = x.copy()
xx, yy = np.meshgrid(x, y)

# Similar to Gaussian func
sigx, sigy = 2, 5
z = 5 * np.exp(-(xx**2 / sigx**2 + yy**2 / sigy**2))

# Plot
fig, ax = plt.subplots(figsize=(6, 6))
ax.pcolormesh(xx, yy, z, cmap='inferno')

# Generating contours
contours = area_contour_image(z, [0.05, 0.3, 0.5, 0.8], ax=ax, x=x, y=y, cmap='Reds', linewidths=1.75)

# Plot customization
ax.set(xlabel='x', ylabel='y', title='Area Contours')
ax.grid(True)
plt.colorbar(contours, ax=ax)
plt.show()

if name == 'main':
test()`

@nabobalis
Copy link
Contributor

nabobalis commented Mar 28, 2024

Hello, i have made few changes to the gist. `import numpy as np import matplotlib.pyplot as plt

Modifying the gist is not the most useful, we can't make suggestions nor does it move this pull request forward.

I would suggest that you take over this pull request, you will need to fetch the original comments from this pull request onto your sunpy fork, then submit a new pull request with any changes you think need to be made as well addressing the comments that i left here?

Does that sound ok? We can also help with any of the steps if you get stuck.

@AquarlisPrime
Copy link

Sure, I would be happy to work upon it. I am new to open source contributions, so I am thankful for your words of guidance.

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

Successfully merging this pull request may close these issues.

None yet

3 participants