【问题标题】:show matplotlib colorbar instead of legend for multiple plots with gradually changing colors显示 matplotlib 颜色条而不是图例,用于具有逐渐变化的颜色的多个绘图
【发布时间】:2015-06-11 11:37:56
【问题描述】:

我正在尝试制作一个简单的图,该图显示了许多属于具有特定顺序的大型数据集的曲线,例如图 1..n。曲线的形状随着 n 的增加而逐渐变化。读者能否确切地看到哪个图属于哪个 n 值并不重要,但他们应该能够猜测 n 是哪个数量级。

因此我会这样做:

nValues = range(0,30)
xValues = np.linspace(0,10)
dataset = [(xValues-5-0.5*n)**2 for n in nValues]
colors = {n: colorsys.hsv_to_rgb(hue,0.9,0.7) for n,hue in zip(nValues,np.linspace(0,0.7,len(nValues)))}
for n in nValues:
    plt.plot(dataset[n],color=colors[n])

(为了清楚起见,这只是示例,我的数据实际上存储在一个不错的 pandas 数据框中。)

而不是图例,我想在绘图旁边添加一个颜色条,可能带有几个刻度线和标签(至少是最小值和最大值),以指示哪种颜色属于 n 的哪个值,但我不知道如何做到这一点。我想如果我真的从 ColorMap 中获取我的绘图颜色,事情可能会更容易,但我也不知道该怎么做,也不知道如何从那里开始。

欢迎大家指点!

【问题讨论】:

标签: python matplotlib data-visualization


【解决方案1】:

@tom 和@Joe Kington 都是对的:这个问题以前被问过。但是,我试图以稍微少一点的努力作为链接的答案来举一个例子。 要使用颜色图(始终将值从 [0,1] 映射到颜色),您首先需要对数据进行规范化。为此,您可以使用 Normalize 类。仅当您打算创建颜色条时才需要 ScalarMappable 实例。

import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
import matplotlib.cm as cm
import numpy as np

# your dataset
nValues = np.arange(0,30)
xValues = np.linspace(0,10)
dataset = [(xValues-5-0.5*n)**2 for n in nValues]

# setup the normalization and the colormap
normalize = mcolors.Normalize(vmin=nValues.min(), vmax=nValues.max())
colormap = cm.jet

# plot
for n in nValues:
    plt.plot(dataset[n], color=colormap(normalize(n)))

# setup the colorbar
scalarmappaple = cm.ScalarMappable(norm=normalize, cmap=colormap)
scalarmappaple.set_array(nValues)
plt.colorbar(scalarmappaple)

# show the figure
plt.show()

结果:

【讨论】:

  • 能否在右侧彩条旁边添加标签?我想只在极端情况下标记它,最好用一些文字标记。例如,标签“0”将替换为“$x=0$”,标签“1”将替换为“$x=1$”。
  • 我同时找到了一个解决方案,所以对于任何搜索的人,请访问 [this answer][1] 。通过在“cmaps”中添加或删除元素,可以调整不同输入的数量。 [1]:stackoverflow.com/questions/55501860/…
【解决方案2】:

这几乎是其他几个问题的重复。关键是 matplotlib 需要一个 ScalarMappable 实例(通常是图像、散点图等)来制作颜色图。如果您不使用创建一个的绘图方法,则很容易伪造一个。您需要一个 Normalize 实例来定义颜色图的最小/最大值/缩放/等,并需要一个 Colormap 实例来定义颜色。

但是,您还有一个额外的问题。您没有使用颜色图,因此您需要构建一个。

这是一个带有离散颜色图的示例:

import numpy as np
import matplotlib.colors as mcolors
import matplotlib.cm
import matplotlib.pyplot as plt

# Your example...
nvalues = range(0,30)
xvalues = np.linspace(0,10)

hsv2rgb = lambda hue: mcolors.hsv_to_rgb([hue,0.9,0.7])
hues = np.linspace(0, 0.7, len(nvalues))
colors = [hsv2rgb(hue) for hue in hues]

dataset = [(xvalues-5-0.5*n)**2 for n in nvalues]

fig, ax = plt.subplots()
for n in nvalues:
    ax.plot(dataset[n], color=colors[n])

# Fake a ScalarMappable so you can display a colormap
cmap, norm = mcolors.from_levels_and_colors(range(len(nvalues) + 1), colors)
sm = matplotlib.cm.ScalarMappable(cmap=cmap, norm=norm)
sm.set_array([])

fig.colorbar(sm)

plt.show()

如果您更喜欢连续的颜色图:

import numpy as np
import matplotlib.colors as mcolors
import matplotlib.cm
import matplotlib.pyplot as plt

# Your example...
nvalues = range(0,30)
xvalues = np.linspace(0,10)

hsv2rgb = lambda hue: mcolors.hsv_to_rgb([hue,0.9,0.7])
hues = np.linspace(0, 0.7, len(nvalues))
colors = [hsv2rgb(hue) for hue in hues]

dataset = [(xvalues-5-0.5*n)**2 for n in nvalues]

fig, ax = plt.subplots()
for n in nvalues:
    ax.plot(dataset[n], color=colors[n])

# Fake a ScalarMappable so you can display a colormap
cmap = mcolors.LinearSegmentedColormap.from_list('my_cmap', colors)
norm = mcolors.Normalize(min(nvalues), max(nvalues))
sm = matplotlib.cm.ScalarMappable(cmap=cmap, norm=norm)
sm.set_array([])

fig.colorbar(sm)

plt.show()

【讨论】:

    【解决方案3】:

    您必须创建一个新的 cmap 这段代码应该可以工作:

    import matplotlib
    import matplotlib.pyplot as plt 
    import colorsys
    import numpy
    
    nValues = range(30)
    xValues = numpy.linspace(0,10)
    dataset = [(xValues-5-0.5*n)**2 for n in nValues]
    colors  = [colorsys.hsv_to_rgb(hue,0.9,0.7) for hue in numpy.linspace(0.,0.7,30)]
    
    fig = plt.figure()
    axe = fig.add_subplot(111)
    trh = [axe.plot(dataset[n],color=colors[n]) for n in nValues] # one line loop for plotting the data with associated color
    cma = matplotlib.colors.ListedColormap(colors, name='from_list', N=None) # creation of a user cmap
    msm = matplotlib.cm.ScalarMappable(cmap=cma) 
    msm.set_array(nValues) 
    fig.colorbar(msm)
    fig.show()
    

    【讨论】:

      猜你喜欢
      • 2015-08-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-12
      • 2021-12-28
      • 2019-05-14
      • 2020-08-01
      相关资源
      最近更新 更多