15

I have problems with a contour-plot using logarithmic color scaling. I want to specify the levels by hand. Matplotlib, however, draws the color bar in a strange fashion -- the labels are not placed well and only one color appears. The idea is based on http://adversus.110mb.com/?cat=8

Is there anybody out there, who can help me? I use the latest git-repository matplotlib version, v1.1.0 (2011年04月21日)

import matplotlib.pyplot as plt
import numpy as np
from matplotlib.mlab import bivariate_normal
from matplotlib.colors import LogNorm
from matplotlib.backends.backend_pdf import PdfPages
delta = 0.5
x = np.arange(-3.0, 4.001, delta)
y = np.arange(-4.0, 3.001, delta)
X, Y = np.meshgrid(x, y)
Z = bivariate_normal(X, Y, 1.0, 1.0, 0.0, 0.0)
fig = plt.figure()
ax = fig.add_subplot(1,1,1)
#axim = ax.imshow(Z, norm = LogNorm())
axim = ax.contourf(X,Y,Z,levels=[1e0,1e-1,1e-2,1e-3],cmap=plt.cm.jet,norm = LogNorm())
cb = fig.colorbar(axim)
pp = PdfPages('fig.pdf')
pp.savefig()
pp.close()
plt.show()

Thank you very much for your help! It works perfect, as you suggested... However, I have another question: Why does matplotlib not allow me to select the number of level lines in the logarithmic mode:

import matplotlib.pyplot as plt
import numpy as np
from matplotlib.mlab import bivariate_normal
from matplotlib.colors import LogNorm
from matplotlib.backends.backend_pdf import PdfPages
delta = 0.5
x = np.arange(-3.0, 4.001, delta)
y = np.arange(-4.0, 3.001, delta)
X, Y = np.meshgrid(x, y)
Z = bivariate_normal(X, Y, 1.0, 1.0, 0.0, 0.0)
fig = plt.figure()
ax = fig.add_subplot(1,1,1)
#axim = ax.imshow(Z, norm = LogNorm())
#axim = ax.contourf(X,Y,Z,levels=[1e-3,1e-2,1e-1,1e0],cmap=plt.cm.jet,norm = LogNorm())
axim = ax.contourf(X,Y,Z,20,cmap=plt.cm.jet,norm = LogNorm())
cb = fig.colorbar(axim)
pp = PdfPages('fig.pdf')
pp.savefig()
pp.close()
plt.show()

https://i.sstatic.net/VeVFQ.png

This was my original problem...

asked Apr 21, 2011 at 18:11

2 Answers 2

17

So it's easily fixed; your order of levels means that the lowest level gets drawn last and therefore covered everything! Try:

axim = ax.contourf(X,Y,Z,levels=[1e-3, 1e-2, 1e-1, 1e0],cmap=plt.cm.jet,norm = LogNorm())

instead and you should get the desired result.

answered Apr 21, 2011 at 18:23
3
  • Thanks, worked! - Maybe you can also answer the second question? Commented Apr 21, 2011 at 19:12
  • @45z23dsa : It seems that the spacing on the LogNorm setting is set to base 10 in the levels - as the data only goes down to ~1e-8 you end you end up with ~8 levels. You can get around this by changing the base yourself. E.g. lev2 = np.arange(np.floor(np.log2(Z.min())-1), np.ceil(np.log2(Z.max())+1) followed by levs = np.power(2, lev_exp) will give you base 2 spaced levels which you can then pass in as the levels argument. However to get exactly, say 20 levels, you need to use a non-standard base. Commented Apr 22, 2011 at 15:27
  • Dear mutzmatron, Thank you for investigating this! So it is probably easier to simply provide a list of levels which I want... So I consider both questions as being solved! Commented Apr 24, 2011 at 8:58
2

It looks like levels expects increasing values. Try changing them to: levels=[1e-3, 1e-2, 1e-1, 1e0] and see if that solves your issue.

answered Apr 21, 2011 at 18:21
1
  • Thanks worked! Maybe you can also answer the second question? Commented Apr 21, 2011 at 19:12

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.