根据投影的 2d 直方图绘制对齐的 x,y 1d 直方图

问题描述 投票:0回答:1

我需要生成与此示例中所示的图像类似的图像:

区别在于,我没有二维散点,而是使用 numpy 的 histogram2d 生成二维直方图,并使用

imshow
gridspec
绘制:

如何将此 2D 直方图投影为水平和垂直直方图(或曲线),使其看起来对齐,就像第一个图像一样?


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

data = # Uploaded to http://pastebin.com/tjLqM9gQ

# Create a meshgrid of coordinates (0,1,...,N) times (0,1,...,N)
y, x = np.mgrid[:len(data[0, :, 0]), :len(data[0, 0, :])]
# duplicating the grids
xcoord, ycoord = np.array([x] * len(data)), np.array([y] * len(data))
# compute histogram with coordinates as x,y
h, xe, ye = np.histogram2d(
    xcoord.ravel(), ycoord.ravel(),
    bins=[len(data[0, 0, :]), len(data[0, :, 0])],
    weights=stars.ravel())

# Projected histograms inx and y
hx, hy = h.sum(axis=0), h.sum(axis=1)

# Define size of figure
fig = plt.figure(figsize=(20, 15))
gs = gridspec.GridSpec(10, 12)

# Define the positions of the subplots.
ax0 = plt.subplot(gs[6:10, 5:9])
axx = plt.subplot(gs[5:6, 5:9])
axy = plt.subplot(gs[6:10, 9:10])

ax0.imshow(h, cmap=plt.cm.viridis, interpolation='nearest',
           origin='lower', vmin=0.)

# Remove tick labels
nullfmt = NullFormatter()
axx.xaxis.set_major_formatter(nullfmt)
axx.yaxis.set_major_formatter(nullfmt)
axy.xaxis.set_major_formatter(nullfmt)
axy.yaxis.set_major_formatter(nullfmt)

# Top plot
axx.plot(hx)
axx.set_xlim(ax0.get_xlim())
# Right plot
axy.plot(hy, range(len(hy)))
axy.set_ylim(ax0.get_ylim())

fig.tight_layout()
plt.savefig('del.png')
python numpy matplotlib histogram
1个回答
2
投票

seaborn.jointplot 可能可以解决问题。

或者,如果您同意边缘分布全部垂直,则可以使用corner

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

N = 10000
D = 2

quantiles_1d = [0.16, 0.84]  # 90% CI
sigmas_2d = (1 - np.exp(-0.5), 1 - np.exp(-2), 1 - np.exp(-9 / 2.0))  # 1, 2, 3 sigma


def generate_data(dim=2):
    """Generate some data."""
    return pd.DataFrame({f"x[{i}]": np.random.normal(0, 1, N) for i in range(dim)})


def plot_with_corner(data: pd.DataFrame):
    import corner
    fig = corner.corner(
        data,
        smooth=0.9,
        label_kwargs=dict(fontsize=30),
        title_kwargs=dict(fontsize=16),
        truth_color="tab:orange",
        quantiles=quantiles_1d,
        levels=sigmas_2d,
        plot_density=False,
        plot_datapoints=False,
        fill_contours=True,
        max_n_ticks=3,
        verbose=False,
        use_math_text=True,
    )
    plt.savefig("corner.png")


def plot_with_seaborn(data):
    import seaborn as sns

    kdeplot = sns.jointplot(
        data=data, x="x[0]", y="x[1]",
        kind="kde", fill=True,
        space=0,
        levels=100,
        cbar=True,
        common_norm=True,
    )

    lkwg = dict(linestyle="-", linewidth=2, color="k")
    # overplot 1, 2, 3 sigma contours
    sns.kdeplot(data=data, x="x[0]", y="x[1]", levels=sigmas_2d, ax=kdeplot.ax_joint, **lkwg)

    # overplot 90% CI quantiles on marginals
    for q in quantiles_1d:
        kdeplot.ax_marg_x.vlines(data["x[0]"].quantile(q), *kdeplot.ax_marg_x.get_ylim(), **lkwg)
        kdeplot.ax_marg_y.hlines(data["x[1]"].quantile(q), *kdeplot.ax_marg_y.get_xlim(), **lkwg)

    # reposition colorbar to right of plot
    # https://stackoverflow.com/a/60962023/10177759
    plt.subplots_adjust(left=0.1, right=0.8, top=0.9, bottom=0.1)
    pos_joint_ax = kdeplot.ax_joint.get_position()
    pos_marg_x_ax = kdeplot.ax_marg_x.get_position()
    kdeplot.ax_joint.set_position([pos_joint_ax.x0, pos_joint_ax.y0, pos_marg_x_ax.width, pos_joint_ax.height])
    cbar_ax = kdeplot.fig.axes[-1]
    cbar_ax.set_position([.83, pos_joint_ax.y0, .07, pos_joint_ax.height])

    # # set ticks and labels for colorbar at sigmas_2d
    _, cbar_max = cbar_ax.get_ylim()
    cbar_sigma2d = [s * cbar_max for s in sigmas_2d]
    cbar_ax.set_yticks(cbar_sigma2d)
    cbar_ax.set_yticklabels([r"$3\sigma$", r"$2\sigma$", r"$1\sigma$"])
    plt.savefig("seaborn.png")


if __name__ == "__main__":
    data = generate_data(dim=D)
    plot_with_corner(data)
    plot_with_seaborn(data)

角落

希博恩

© www.soinside.com 2019 - 2024. All rights reserved.