本文介绍了matplotlib等高线图:对数比例的比例色条水平的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以像下面的图片那样以对数刻度显示颜色条的水平?

Would it be possible to have levels of the colorbar in log scale like in the image below?

以下是一些可以在其中实现的示例代码:

Here is some sample code where it could be implemented:

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一起使用.

I am using python 2.7.3 with matplotlib 1.1.1 on Windows 7.

推荐答案

我建议生成一个伪彩色条,如下所示(有关说明,请参见注释):

I propose to generate a pseudo colorbar as follows (see comments for explanations):

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()

这会给你这样的情节:

编辑

或者,在调用colorbar时使用新级别和spacing='proportional'选项之类的东西:

Or, use something like the new levels and the spacing='proportional' option when calling the colorbar:

  1. 替换此行:

  1. replace this line:

lvls = np.logspace(0,4,20)

包含以下内容:

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)))

  • 替换此行:

  • replace this line:

    cbar = plt.colorbar(CF, ticks=lvls, format='%.4f')
    

    与此:

    cbar = plt.colorbar(CF, ticks=lvls, format='%.2f', spacing='proportional')
    

  • 您将得到以下情节:

    (仅更改了format,因为新的刻度线不需要4位小数)

    (the format was only changed, because the new ticks do not require 4 decimals)

    编辑2
    如果您想自动生成类似我使用过的级别,可以考虑以下代码:

    EDIT 2
    If you wanted to automatically generate levels like the ones I have used, you can consider this piece of code:

    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)))
    

    这篇关于matplotlib等高线图:对数比例的比例色条水平的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

    08-29 04:15