如何在python中格式化角点图?

时间:2019-06-14 00:22:23

标签: python plot mcmc

我有一些类似emcee的程序包,该程序包运行mcmc算法以进行模型拟合。一旦获得了后采样链,就可以使用包corner来生成corner图。我的一些参数很大,而另一些则很小。因此,该图看起来很奇怪(如右图所示)。enter image description here

有没有一种方法可以用科学计数法显示大量数字,而将少量数字显示为浮点数? x轴刻度标签已经具有此功能。我希望合适的结果标题也一样。

1 个答案:

答案 0 :(得分:2)

使用title_fmt

您可以使用kwarg title_fmt设置标题格式:

title_fmt:字符串

    The format string for the quantiles given in titles. If you explicitly
    set ``show_titles=True`` and ``title_fmt=None``, the labels will be
    shown as the titles. (default: ``.2f``)

根据您的情况,您可以设置title_fmt=".2E"

示例

在指定title_fmt之前:

before

指定title_fmt=".2E"后:

after

例如代码

# -*- coding: utf-8 -*-
"""Corner on top of each other"""
import corner
import matplotlib.lines as mlines
import matplotlib.pyplot as plt
import numpy as np

CORNER_KWARGS = dict(
    smooth=0.9,
    label_kwargs=dict(fontsize=16),
    title_kwargs=dict(fontsize=16),
    quantiles=[0.16, 0.84],
    levels=(1 - np.exp(-0.5), 1 - np.exp(-2), 1 - np.exp(-9 / 2.)),
    plot_density=False,
    plot_datapoints=False,
    fill_contours=True,
    show_titles=True,
    max_n_ticks=3,
    title_fmt=".2E"
)


def overlaid_corner(samples_list, sample_labels):
    """Plots multiple corners on top of each other"""
    # get some constants
    n = len(samples_list)
    _, ndim = samples_list[0].shape
    max_len = max([len(s) for s in samples_list])
    cmap = plt.cm.get_cmap('gist_rainbow', n)
    colors = [cmap(i) for i in range(n)]

    plot_range = []
    for dim in range(ndim):
        plot_range.append(
            [
                min([min(samples_list[i].T[dim]) for i in range(n)]),
                max([max(samples_list[i].T[dim]) for i in range(n)]),
            ]
        )

    CORNER_KWARGS.update(range=plot_range)

    fig = corner.corner(
        samples_list[0],
        color=colors[0],
        **CORNER_KWARGS
    )

    for idx in range(1, n):
        fig = corner.corner(
            samples_list[idx],
            fig=fig,
            weights=get_normalisation_weight(len(samples_list[idx]), max_len),
            color=colors[idx],
            **CORNER_KWARGS
        )

    plt.legend(
        handles=[
            mlines.Line2D([], [], color=colors[i], label=sample_labels[i])
            for i in range(n)
        ],
        fontsize=20, frameon=False,
        bbox_to_anchor=(1, ndim), loc="upper right"
    )
    plt.savefig("orig_corner.png")
    plt.close()


def get_normalisation_weight(len_current_samples, len_of_longest_samples):
    return np.ones(len_current_samples) * (len_of_longest_samples / len_current_samples)


def main():
    ndim, nsamples = 3, 10000
    np.random.seed(2000)
    samples = np.random.randn(ndim * nsamples).reshape([nsamples, ndim]) * 1e9

    overlaid_corner(
        [samples * 3, samples * 2, samples],
        ["samples x 3", "samples x 2", "samples"]
    )


if __name__ == "__main__":
    main()