Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
575 views
in Technique[技术] by (71.8m points)

matplotlib - Python: setting the zero value color in a contourf plot, where log scale colorbar is required

I am trying to make a contour plot from some data files. The trouble I am having is that I want the z-values below the minimum on the color bar to be the same color as the minimum value. This is easy when using a linear scale using e.g. the extend="both" option for the contourf, or using cmap.set_under() for the colormap. Unfortunately neither of those options work when using a logscale. Can anyone suggest a workaround? I just want to get rid of the white areas in the plot below:

enter image description here

#!/usr/bin/env python
import numpy as np
import matplotlib.pyplot as plt
import scipy.interpolate
from matplotlib import colors, ticker, cm
from matplotlib.colors import LogNorm
N = 100 #number of points for plotting/interpolation

y, x, z = np.genfromtxt(r'40Ca_208Pb_39K_Ex_115deg.dat', unpack=True)

xi = np.linspace(x.min(), x.max(), N)
yi = np.linspace(y.min(), y.max(), N)
zi = scipy.interpolate.griddata((x, y), z, (xi[None,:], yi[:,None]), method='linear')

hfont = {'fontname':'Palatino'}

fig = plt.figure(facecolor="white")

zi = np.ma.masked_less(zi, 1e-7) 

plt.contourf(xi, yi, zi,levels=[1e-7,1e-6,1e-5,1e-4,1e-3,1e-2,1e-1],cmap=plt.cm.jet,norm = LogNorm())

plt.xlabel("$E_{x}$")
plt.ylabel("$E/V_{B}$") 
plt.colorbar()
plt.show()
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

It appears that the extend keyword not working with a log scale is a known issue with matplotlib.

A crude workaround would be to coerce all the values into the drawn range (notice the comments on the min_drawn_value and max_drawn_value, the values must be inside that range):

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import LogNorm

N = 100  # number of points for plotting/interpolation
min_exp = -8
max_exp = -2

min_drawn_value = 1.000001 * 10.**min_exp  # above 10.**min_exp
max_drawn_value = 0.999999 * 10.**max_exp  # below 10.**max_exp

xi = np.linspace(0, 1, N)
yi = np.linspace(0, 1, N)
zi = np.random.rand(N, N) *
     10. ** np.random.randint(min_exp - 1, max_exp + 2, (N, N))
zi = np.sort(zi.flatten()).reshape(N,N)

# Coerce values outside of colorbar range to lie within
zi_masked = np.where(zi < 10.**min_exp, min_drawn_value, zi)
zi_masked = np.where(zi_masked > 10.**max_exp, max_drawn_value, zi_masked)


fig, (ax,ax2) = plt.subplots(ncols=2)

c1 = ax.contourf(xi, yi, zi, levels=10.**np.arange(min_exp, max_exp+1),
             cmap=plt.cm.jet, norm=LogNorm())

c2 = ax2.contourf(xi, yi, zi_masked, levels=10.**np.arange(min_exp, max_exp+1),
             cmap=plt.cm.jet, norm=LogNorm())

ax.set_title("direct plot of array")
ax2.set_title("coerce outlier values")
fig.colorbar(c1, ax=ax)
fig.colorbar(c2, ax=ax2)
fig.subplots_adjust(wspace=0.3)
plt.show()

enter image description here


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...