【问题标题】:Overlaying plots on a single graph在单个图形上叠加图
【发布时间】:2018-12-25 18:03:17
【问题描述】:

我有两个基于 2d 直方图的热图,我试图将它们叠加在一个图表上。它们的轴(extent_L 和extent_H)的界限不一定完全重合。如果需要,我可以令人满意地制作各个图,但是当试图在一个图表上很好地显示两个热图时,只会显示最近的一个。

import numpy as np
import numpy.random
import matplotlib.pyplot as plt

# Generate some test data
x_L = np.random.randn(8873)
y_L = np.random.randn(8873)

x_H = np.random.randn(1000)
y_H = np.random.randn(1000)

heatmap_L, xedges_L, yedges_L = np.histogram2d(x_L, y_L, bins=50)
extent_L = [xedges_L[0], xedges_L[-1], yedges_L[0], yedges_L[-1]]

heatmap_H, xedges_H, yedges_H = np.histogram2d(x_H, y_H, bins=50)
extent_H = [xedges_H[0], xedges_H[-1], yedges_H[0], yedges_H[-1]]

plt.clf()
im1 = plt.imshow(heatmap_L.T, extent=extent_L, origin='lower', cmap='Blues')
im2 = plt.imshow(heatmap_H.T, extent=extent_H, origin='lower', cmap='Greens')
plt.show() 

编辑:如果我没记错的话,所有点都不在正确的位置

import numpy as np
import numpy.random
import matplotlib.pyplot as plt

# Generate some test data
x_L = np.random.randn(8873)
y_L = np.random.randn(8873)

x_H = np.random.randn(1000)
y_H = np.random.randn(1000)

heatmap_L, xedges_L, yedges_L = np.histogram2d(x_L, y_L, bins=50)
extent_L = np.array([xedges_L[0], xedges_L[-1], yedges_L[0], yedges_L[-1]])

heatmap_H, xedges_H, yedges_H = np.histogram2d(x_H, y_H, bins=50)
extent_H = np.array([xedges_H[0], xedges_H[-1], yedges_H[0], yedges_H[-1]])

plt.clf()
im1 = plt.imshow(heatmap_L.T, extent=extent_L, origin='lower', cmap='Blues')
im2 = plt.imshow(heatmap_H.T, extent=extent_H, origin='lower', cmap='Greens')
plt.autoscale()
plt.show()

flatHMH = np.reshape(heatmap_H, 2500)  # flatten the 2D arrays
flatHML = np.reshape(heatmap_L, 2500)
maxHMH = flatHMH.max()  # Find the maximum in each
maxHML = flatHML.max()
# Now for each value in the flat array build an RGBA tuple using 
# 1 for the colour we want - either green or blue, and then scaling
# the value by the maximum, finally reshaping back to a 50x50 array
augHMH = np.array([(0, 1, 0, x/maxHMH) for x in flatHMH]).reshape((50, 50, 4))
augHML = np.array([(0, 0, 1, x/maxHML) for x in flatHML]).reshape((50, 50, 4))

plt.clf()
# Plot without cmap as colours are now part of the data array passed.
im1 = plt.imshow(augHML, extent=extent_L, origin='lower')
im2 = plt.imshow(augHMH, extent=extent_H, origin='lower')
plt.autoscale()
plt.show()

如果您仔细观察最后一个图中的点,例如边缘点的聚类,您会发现它们与上图中的不同。

【问题讨论】:

  • @ImportanceOfBeingErnest 它实际上遵循this example,它为一个情节的情况提供了一个工作示例。我有兴趣叠加两个这样的图。

标签: python matplotlib histogram heatmap imshow


【解决方案1】:

您正在显示两个图,问题是您在另一个之上绘制一个。要查看实际情况,您可以移动其中一个图,如下所示:

import numpy as np
import numpy.random
import matplotlib.pyplot as plt

# Generate some test data
x_L = np.random.randn(8873)
y_L = np.random.randn(8873)

x_H = np.random.randn(1000)
y_H = np.random.randn(1000)

heatmap_L, xedges_L, yedges_L = np.histogram2d(x_L, y_L, bins=50)
extent_L = np.array([xedges_L[0], xedges_L[-1], yedges_L[0], yedges_L[-1]])

heatmap_H, xedges_H, yedges_H = np.histogram2d(x_H, y_H, bins=50)
extent_H = np.array([xedges_H[0], xedges_H[-1], yedges_H[0], yedges_H[-1]])

plt.clf()
im1 = plt.imshow(heatmap_L.T, extent=extent_L, origin='lower', cmap='Blues')
im2 = plt.imshow(heatmap_H.T+2, extent=extent_H+2, origin='lower', cmap='Greens')
plt.autoscale()
plt.show() 

您还需要在那里调用plt.autoscale(),否则限制不会正确调整。

将两个图相互叠加显示的一种方法是将参数alpha=X 用于imshow 调用(其中0 the imshow docs,了解将图相互叠加显示的两种选择。

转换值的一种方法是展平数据,并用所需的颜色对其进行扩充。

# imports and test data generation as before, removed for clarity...

flatHMH = np.reshape(heatmap_H, 2500)  # flatten the 2D arrays
flatHML = np.reshape(heatmap_L, 2500)
maxHMH = flatHMH.max()  # Find the maximum in each
maxHML = flatHML.max()
# Now for each value in the flat array build an RGBA tuple using 
# 1 for the colour we want - either green or blue, and then scaling
# the value by the maximum, finally reshaping back to a 50x50 array
augHMH = np.array([(0, 1, 0, x/maxHMH) for x in flatHMH]).reshape((50, 50, 4))
augHML = np.array([(0, 0, 1, x/maxHML) for x in flatHML]).reshape((50, 50, 4))

plt.clf()
# Plot without cmap as colours are now part of the data array passed.
im1 = plt.imshow(augHML, extent=extent_L, origin='lower')
im2 = plt.imshow(augHMH, extent=extent_H, origin='lower')
plt.autoscale()
plt.show() 

【讨论】:

  • 是的,alpha 有助于混合,但如果它太低,则它看起来完全被涂抹,没有明显区分集中点。但是如果 alpha 太高,那么每个重叠图中的矩形网格会变得非常明显。有没有一种最佳方法可以很好地融合叠加图的背景,同时保持集中点引人注目?
  • @Mathews24,请参阅 imshow 文档中先前提示的替代解决方案的更新答案。
  • 根据我的可视化,似乎点可能与原始案例不完全对齐。当我绘制上面的(第一个例子)然后用 RGB 绘制后一个例子时,这些点不一定在网格上的完全相同的位置。我将在编辑我的原始问题时提供一个示例。
【解决方案2】:

你可以打电话

plt.autoscale()

这样可以根据轴的内容调整限制。

例子:

import numpy as np
import matplotlib.pyplot as plt

def get(offs=0):
    # Generate some test data
    x = np.random.randn(8873)+offs
    y = np.random.randn(8873)+offs

    heatmap, xedges, yedges = np.histogram2d(x, y, bins=50)
    extent = [xedges[0], xedges[-1], yedges[0], yedges[-1]]

    heatmap, xedges, yedges = np.histogram2d(x, y, bins=50)
    extent = [xedges[0], xedges[-1], yedges[0], yedges[-1]]
    return heatmap, extent

h1,e1  = get(-3)
h2,e2  = get(+3)
plt.imshow(h1, extent=e1, origin='lower', cmap="RdBu")
plt.imshow(h2, extent=e2, origin='lower', cmap="YlGnBu")
plt.autoscale()
plt.show()

【讨论】:

  • 谢谢。我已经对此进行了测试,但无法覆盖这些图以确认它是否必须按预期进行调整。
猜你喜欢
  • 1970-01-01
  • 2021-03-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多