user338095
user338095

Reputation: 107

Setting labels manually in matplotlib contour-plot wrong

I am trying to add manual labels to the contourplot in the code below. The labels are printed somewhat randomly. Does anyone have an idea how to fix this? It seems to be a bug in Matplotlib.

Regards, David

import numpy as np
import matplotlib.pyplot as plt

a = 0.2

resolution = 100
xarray = np.linspace(0,0.25,num=resolution)
yarray = np.linspace(0,1,num=resolution)

A = np.empty([resolution,resolution])

xc = 0
yc = 0
for x in xarray:
    for y in yarray:
        #print xc,yc

        wp = 1./np.pi*np.arctan(np.sin(np.pi*y)*np.sinh(np.pi*a/2.)/
              (np.cosh(np.pi*x)-np.cos(np.pi*y)*np.cosh(np.pi*a/2.)))

        if wp <= 0:
            wp = wp+1
            A[xc, yc] = wp
        else:
            A[xc, yc] = wp
        yc += 1
    yc=0
    xc += 1

A = A.transpose()
B = np.fliplr(A)
AB = np.hstack((B,A))
fullx = np.hstack((-xarray[::-1],xarray))

#plot
fig = plt.figure()
fig.suptitle("Weighting potential")
ax = plt.subplot(1,1,1)
CS = plt.contour(fullx,yarray,AB,10, colors='k')

labelpos = np.dstack((np.zeros(9),np.arange(0.1,1,0.1)))[0]
plt.clabel(CS,inline=True, fmt='%1.1f',fontsize=9, manual=labelpos)

plt.show()

enter image description here

Upvotes: 5

Views: 1505

Answers (1)

Saullo G. P. Castro
Saullo G. P. Castro

Reputation: 59005

This is the expected behavior.

It picks the closest contour curve for a each x, y data coordinate contained in the manual parameter. When the same contour curve is found for many coordinates, it may happen they will start to agglomerate, as in your case.

If you used:

y_pick = [0.01, 0.025, 0.05, 0.075, 0.1, 0.15, 0.2, 0.3, 0.5]
labelpos = ((0, i) for i in y_pick)

you would get something like:

enter image description here


Out of topic:

you can vectorize your code avoiding the relatively slow for loops:

import numpy as np
import matplotlib.pyplot as plt

a = 0.2

def fwp(x, y, a):
    return (1./np.pi*np.arctan(np.sin(np.pi*y)*np.sinh(np.pi*a/2.)/
          (np.cosh(np.pi*x)-np.cos(np.pi*y)*np.cosh(np.pi*a/2.))))

resolution = 100
xarray = np.linspace(0, 0.25, num=resolution)
yarray = np.linspace(0, 1, num=resolution)
x, y = np.meshgrid(xarray, yarray, copy=False)
A = fwp(x, y, a)
A[A<=0] += 1
B = np.fliplr(A)
AB = np.hstack((B, A))

Upvotes: 2

Related Questions