在保持对齐的同时调整 scipy 树状图和 matplotlib pcolor 子图的大小

Resizing scipy dendrogram and matplotlib pcolor subplots while keeping alignment

目标

像 matlab 制作的那样制作连接到热图的树状图;

或者像 this plotly example 那样没有花哨的 javascript 只使用 scipy 和 matplotlib。

建立在 this question 的基础上,我导出了以下代码;

输入

from scipy.cluster.hierarchy import linkage
from scipy.cluster.hierarchy import dendrogram
from scipy.spatial.distance import pdist
import matplotlib
from matplotlib import pyplot as plt
import numpy as np
from numpy import arange

# Create the figure and set it's size.
fig = plt.figure(figsize=(5,7))

# Create the first subplot in the figure. 
ax1 = plt.subplot(211)

# Set to your favorite colormap.
cm = matplotlib.cm.viridis

# Create array of random numbers.
X = np.random.random([6,300])

# Create a linkage object.
linkmat = linkage(X)

# Make a dendrogram from the linkage object.
dendrogram(linkmat)

# Use the x and y limits to set the aspect.
x0,x1 = ax1.get_xlim()
y0,y1 = ax1.get_ylim()
ax1.set_aspect((x1-x0)/(y1-y0))


# Remove the ticks on the x-axis. 
plt.tick_params(axis='x', which='both', bottom='off', top='off', labelbottom='off')

# Create the second subplot.
ax2 = plt.subplot(212)

labels = ["a", "b", "c", "d", "e"]

plt.xticks(arange(0.5, 7.5, 1))

plt.gca().set_xticklabels(labels)

plt.pcolor(X.T)

x0,x1 = ax2.get_xlim()
y0,y1 = ax2.get_ylim()

ax2.set_aspect((x1-x0)/(y1-y0))

# Insert the color scale
plt.colorbar()
cb = plt.colorbar(ax=ax1)
cb.ax.set_visible(False)

# Make the vertical distance between plots equal to zero 
plt.subplots_adjust(hspace=0)

# Show the plot
plt.show()

输出

问题

我怎样才能减少树状图的高度 50% 和 增加 热图的高度 50%,同时保持它们当前的高度对齐方式?

您可以使用 subplot2grid({params}) 而不是 subplot(),因为您可以知道它将占据多少个网格

from scipy.cluster.hierarchy import linkage
from scipy.cluster.hierarchy import dendrogram
from scipy.spatial.distance import pdist
import matplotlib
from matplotlib import pyplot as plt
import numpy as np
from numpy import arange

# Create the figure and set it's size.
fig = plt.figure(figsize=(5,7))

# Create the first subplot in the figure. 
ax1 = plt.subplot2grid((3, 1), (0, 0), rowspan= 1, colspan=1)

# Set to your favorite colormap.
cm = matplotlib.cm.viridis

# Create array of random numbers.
X = np.random.random([6,300])

# Create a linkage object.
linkmat = linkage(X)

# Make a dendrogram from the linkage object.
dendrogram(linkmat)

# Use the x and y limits to set the aspect.
x0,x1 = ax1.get_xlim()
y0,y1 = ax1.get_ylim()
#ax1.set_aspect((x1-x0)/(y1-y0))


# Remove the ticks on the x-axis. 
plt.tick_params(axis='x', which='both', bottom='off', top='off', labelbottom='off')

# Create the second subplot.
ax2 = plt.subplot2grid((3, 1), (1, 0), rowspan= 2, colspan=1)

labels = ["a", "b", "c", "d", "e"]

plt.xticks(arange(0.5, 7.5, 1))

plt.gca().set_xticklabels(labels)

plt.pcolor(X.T)

x0,x1 = ax2.get_xlim()
y0,y1 = ax2.get_ylim()

#ax2.set_aspect((x1-x0)/(y1-y0))

# Insert the color scale
plt.colorbar()
cb = plt.colorbar(ax=ax1)
cb.ax.set_visible(False)

# Make the vertical distance between plots equal to zero 
plt.subplots_adjust(hspace=0)

# Show the plot
plt.show()