gpt4 book ai didi

python - 调整顶部和右侧联合边缘图的轴大小以匹配中心图与 matplotlib

转载 作者:行者123 更新时间:2023-12-05 05:46:50 25 4
gpt4 key购买 nike

如何使用 matplotlib 调整边缘图的轴大小以匹配非方形中心图的大小?

Joint plot with overly-wide top marginal plot

在图像中,您会看到顶部边缘图太宽,即使它共享 x 轴标签。

上下文:我正在尝试创建联合图 like in Seaborn ,但在中心有一个非正方形热图,在边际图上有条形图。 JointGrids不适用于热图(没关系,继续使用 matplotlib!)。合并 matplotlib heatmap使用子图条形图让我很接近,但我发现一个条形图的轴比中心热图大,即使我共享轴也是如此。

最小工作示例:

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd

### Function from matplotlib ################################################
def heatmap(data, row_labels, col_labels, ax=None,
cbar_kw={}, cbarlabel="", **kwargs):
"""
Create a heatmap from a numpy array and two lists of labels.

Parameters
----------
data
A 2D numpy array of shape (M, N).
row_labels
A list or array of length M with the labels for the rows.
col_labels
A list or array of length N with the labels for the columns.
ax
A `matplotlib.axes.Axes` instance to which the heatmap is plotted. If
not provided, use current axes or create a new one. Optional.
cbar_kw
A dictionary with arguments to `matplotlib.Figure.colorbar`. Optional.
cbarlabel
The label for the colorbar. Optional.
**kwargs
All other arguments are forwarded to `imshow`.
"""

if not ax:
ax = plt.gca()

# Plot the heatmap
im = ax.imshow(data, **kwargs)

# Create colorbar
cbar = ax.figure.colorbar(im, ax=ax, **cbar_kw)
cbar.ax.set_ylabel(cbarlabel, rotation=-90, va="bottom")

# Show all ticks and label them with the respective list entries.
ax.set_xticks(np.arange(data.shape[1]), labels=col_labels)
ax.set_yticks(np.arange(data.shape[0]), labels=row_labels)

# Rotate the tick labels and set their alignment.
plt.setp(ax.get_xticklabels(), rotation=-30, ha="right",
rotation_mode="anchor")

# Turn spines off and create white grid.
ax.spines[:].set_visible(False)

ax.set_xticks(np.arange(data.shape[1]+1)-.5, minor=True)
ax.set_yticks(np.arange(data.shape[0]+1)-.5, minor=True)
ax.grid(which="minor", color="w", linestyle='-', linewidth=3)
ax.tick_params(which="minor", bottom=False, left=False)

return im, cbar

### Now this specific case ################################################

# Make dataframe
dd = {f'Col_{col}': [col*x**2 for x in range(25)] for col in range(16)}
index = [f'Row_{x}' for x in range(25)]
df = pd.DataFrame(dd, index=index)

# Make means by axis
ax0_means = df.mean(axis=0)
ax1_means = df.mean(axis=1)

# Build figure and axes
fig, axs = plt.subplots(2, 2, sharex="col", sharey="row", figsize=(16,16),
gridspec_kw=dict(height_ratios=[1, 3],width_ratios=[3, 1]))
axs[0, 1].set_visible(False)
axs[0, 0].set_box_aspect(1/3)
axs[1, 1].set_box_aspect(3/1)

# Plot data
im, cbar = heatmap(df, df.index, df.columns, ax=axs[1,0])
plt.setp(axs[1,0].get_xticklabels(), rotation=45, ha="right",
rotation_mode="anchor")

# Rotate the tick labels and set their alignment.
axs[1, 1].barh(y=ax1_means.index, width=ax1_means.values)
axs[0, 0].bar(x=ax0_means.index, height=ax0_means.values)
plt.show()

最佳答案

由于热图获得默认的“相等”纵横比,并且由于颜色条而缩小,因此一个想法是在创建所有内容后手动调整直方图的大小。

from matplotlib.transforms import Bbox

# code added at the end, just before plt.show()
(x0m, y0m), (x1m, y1m) = axs[1, 0].get_position().get_points() # main heatmap
(x0h, y0h), (x1h, y1h) = axs[0, 0].get_position().get_points() # horizontal histogram
axs[0, 0].set_position(Bbox([[x0m, y0h], [x1m, y1h]]))
(x0v, y0v), (x1v, y1v) = axs[1, 1].get_position().get_points() # vertical histogram
axs[1, 1].set_position(Bbox([[x0v, y0m], [x1v, y1m]]))

plt.show()

(以下示例在gridspec_kw=中使用了hspace=0.01,wspace=0.02)

heatmap with equal aspect ratio and histograms

关于python - 调整顶部和右侧联合边缘图的轴大小以匹配中心图与 matplotlib,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71119762/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com