2

The example code creates a 2D visualization of angles relative to the center. Contour lines with labels are added to show lines of constant angle.

import numpy as np
import matplotlib.pyplot as plt

n = 200
x = np.arange(n)
y = np.arange(n)
X, Y = np.meshgrid(x, y)

Z = np.arctan2(Y-n/2, X-n/2)

plt.imshow(Z, cmap='twilight')
contours = plt.contour(X, Y, Z)
plt.clabel(contours)
plt.show()

enter image description here

You can see that all contours are overlapping at the negative x-axis, which corresponds to an angle of π of -π. How can I prevent this and only plot one contour line?

5
  • "You can see that all contours are overlapping at the negative x-axis" << Can I? How am I supposed to see that? Commented Oct 17 at 9:20
  • 1
    @Stef there are multiple horizontal lines from the centre of the plot to the left, labelled with -2.4, 0.8, -0.8 and 2.4. Commented Oct 17 at 9:43
  • Your problem is that either side of the line to the negative side of the centre origin there is a hard discontinuity of 2pi across the x-axis. So as far as the program is concerned the contours are very tightly spaced there - i.e. sat on top of each other. It also looks slightly twisted and warped near the origin viewed at full resolution. The contour lines to the negative side of the origin are 1 or 2 pixels too high. Commented Oct 17 at 14:00
  • 1
    Why do you want to avoid it? You have a natural discontinuity there associated with the principal values of arctan. The polar angle at the origin is also ambiguous. Commented Oct 18 at 5:21
  • @lastchance, sorry for the late answer. I am working with values lying on the unit circle. This means that -pi == pi == pi + k2pi with k an integer. There isn't really a discontinuity. As for the origin, it is no problem for me. This was just a simple example to explain my problem Commented Oct 21 at 19:56

1 Answer 1

2

This worked for me, although I couldn't figure out how to set the original values with clabels.

import matplotlib.pyplot as plt
import numpy as np


def cyclic_contour(x, y, z, period, shift_fraction=0.25, levels=None, **contour_kwargs):
    z_clean = z.copy()
    z_clean[np.isclose(z, period)] = np.nan
    z_clean[np.isclose(z, 0)] = np.nan

    contours = plt.contour(x, y, z_clean, levels=levels, **contour_kwargs)

    z_shifted = (z_wrapped + shift_fraction * period) % period
    z_shifted[np.isclose(z_shifted, 0)] = np.nan

    seam_level = shift_fraction * period
    seam = plt.contour(x, y, z_shifted, levels=[seam_level], **contour_kwargs)
    seam.levels = [0.0]

    return contours, seam


n = 200
x, y = np.indices((n, n))
z = np.arctan2(y - n / 2, x - n / 2)
period = 2 * np.pi
z_wrapped = z % period

contours, seam = cyclic_contour(
    x, y, z_wrapped, period=period, levels=np.linspace(0, 2 * np.pi, 9), colors="black"
)
plt.clabel(contours, fmt="%.2f")
plt.clabel(seam, fmt="%.2f")
plt.imshow(z, cmap="twilight")
plt.show()
Sign up to request clarification or add additional context in comments.

Comments

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.