matplotlib contour plot: proportional colorbar levels in logarithmic scale
是否可以像下面的图像那样以对数刻度显示颜色条级别?
这是一些可以实现的示例代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | import matplotlib.pyplot as plt import numpy as np from matplotlib.colors import LogNorm delta = 0.025 x = y = np.arange(0, 3.01, delta) X, Y = np.meshgrid(x, y) Z1 = plt.mlab.bivariate_normal(X, Y, 1.0, 1.0, 0.0, 0.0) Z2 = plt.mlab.bivariate_normal(X, Y, 1.5, 0.5, 1, 1) Z = 1e6 * (Z1* Z2) fig=plt.figure() ax1 = fig.add_subplot(111) lvls = np.logspace(0,4,20) CF = ax1.contourf(X,Y,Z, norm = LogNorm(), levels = lvls ) CS = ax1.contour(X,Y,Z, norm = LogNorm(), colors = 'k', levels = lvls ) cbar = plt.colorbar(CF, ticks=lvls, format='%.4f') plt.show() |
我在Windows 7上将python 2.7.3与matplotlib 1.1.1一起使用。
我建议生成一个伪彩色条,如下所示(有关说明,请参见注释):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | import matplotlib.pyplot as plt import numpy as np from matplotlib.colors import LogNorm import matplotlib.gridspec as gridspec delta = 0.025 x = y = np.arange(0, 3.01, delta) X, Y = np.meshgrid(x, y) Z1 = plt.mlab.bivariate_normal(X, Y, 1.0, 1.0, 0.0, 0.0) Z2 = plt.mlab.bivariate_normal(X, Y, 1.5, 0.5, 1, 1) Z = 1e6 * (Z1 * Z2) fig=plt.figure() # # define 2 subplots, using gridspec to control the # width ratios: # # note: you have to import matplotlib.gridspec for this # gs = gridspec.GridSpec(1, 2,width_ratios=[15,1]) # the 1st subplot ax1 = plt.subplot(gs[0]) lvls = np.logspace(0,4,20) CF = ax1.contourf(X,Y,Z, norm = LogNorm(), levels = lvls ) CS = ax1.contour(X,Y,Z, norm = LogNorm(), colors = 'k', levels = lvls ) # # the pseudo-colorbar # # the 2nd subplot ax2 = plt.subplot(gs[1]) # # new levels! # # np.logspace gives you logarithmically spaced levels - # this, however, is not what you want in your colorbar # # you want equally spaced labels for each exponential group: # levls = np.linspace(1,10,10) levls = np.concatenate((levls[:-1],np.linspace(10,100,10))) levls = np.concatenate((levls[:-1],np.linspace(100,1000,10))) levls = np.concatenate((levls[:-1],np.linspace(1000,10000,10))) # # simple x,y setup for a contourf plot to serve as colorbar # XC = [np.zeros(len(levls)), np.ones(len(levls))] YC = [levls, levls] CM = ax2.contourf(XC,YC,YC, levels=levls, norm = LogNorm()) # log y-scale ax2.set_yscale('log') # y-labels on the right ax2.yaxis.tick_right() # no x-ticks ax2.set_xticks([]) plt.show() |
这会给你这样的情节:
编辑
或者,在调用
替换此行:
1 | lvls = np.logspace(0,4,20) |
用这些:
1 2 3 4 | lvls = np.linspace(1,10,5) lvls = np.concatenate((lvls[:-1],np.linspace(10,100,5))) lvls = np.concatenate((lvls[:-1],np.linspace(100,1000,5))) lvls = np.concatenate((lvls[:-1],np.linspace(1000,10000,5))) |
替换此行:
1 | cbar = plt.colorbar(CF, ticks=lvls, format='%.4f') |
有了这个:
1 | cbar = plt.colorbar(CF, ticks=lvls, format='%.2f', spacing='proportional') |
您将得到以下情节:
(仅更改了
编辑2
如果您想自动生成类似我使用过的级别,可以考虑以下代码:
1 2 3 4 5 | levels = [] LAST_EXP = 4 N_LEVELS = 5 for E in range(0,LAST_EXP): levels = np.concatenate((levels[:-1],np.linspace(10**E,10**(E+1),N_LEVELS))) |