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...
2 Answers 2
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.
-
Thanks, worked! - Maybe you can also answer the second question?7asd23hasd– 7asd23hasd2011年04月21日 19:12:25 +00:00Commented 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 bylevs = np.power(2, lev_exp)
will give you base 2 spaced levels which you can then pass in as thelevels
argument. However to get exactly, say 20 levels, you need to use a non-standard base.jmetz– jmetz2011年04月22日 15:27:55 +00:00Commented 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!7asd23hasd– 7asd23hasd2011年04月24日 08:58:50 +00:00Commented Apr 24, 2011 at 8:58
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.
-
Thanks worked! Maybe you can also answer the second question?7asd23hasd– 7asd23hasd2011年04月21日 19:12:00 +00:00Commented Apr 21, 2011 at 19:12
Explore related questions
See similar questions with these tags.