Page 1 of 1

GetDist: Showing 1D constrain on 2D plane

Posted: August 12 2022
by José Ferreira
Hi,

First of all, apologies if the title is not very clear, but I don't know how to summarize what I'm trying to achieve any better.

Using my specific case as an example, I have a dataset which constrains my model in both parameters $h$ and $\Omega_m$, whereas the other dataset only sets constrains on $\Omega_m$.
If I try to plot them together, it looks like the following:
Image

You can immediately see two problems which I'm trying to tackle:
1. The constrains don't show up on the $h$ vs $\Omega_m$ plane as a rectangle with the corresponding 1$\sigma$ and 2$\sigma$ regions;
2. The legend for the 1D constrains on $\Omega_m$ isn't rendered by GetDist.

I used GIMP to show how I would like this plot to look like:
Image

However, after searching around in this forum and in the documentation, I found no solution to either of these problems and therefore would like to ask for assistance.
Ideas for workarounds to these issues included manually looking at the regions provided by the plot in red and using matplotlib itself trying to add the region my hand but I failed to do that. The same thing happened for the legend.

Thanks in advance.

Re: GetDist: Showing 1D constrain on 2D plane

Posted: August 14 2022
by Antony Lewis

Re: GetDist: Showing 1D constrain on 2D plane

Posted: August 15 2022
by José Ferreira
Ah, I should have seen that one, many thanks.

With respect to the legend, I didn't found a good solution to the problem, as no matter what, it doesn't seem to be able to add a legend when one of the dataset is only present in 1D.
So what I did what finding a (very awful) workaround by disabling the legend of the plot and creating one by hand.
Here's a snippet of what the code looks like, in case somebody is interested or wishes to improve on this solution:

Code: Select all

# also assume the required packages are being imported
# assume that mcsamples is a set of samples from an MCMC...

# init and config plot
markers = None
contour_alpha = 0.5
colors = ["#006FED", "#E03424", "#008000"]
contour_colors = ["#006FED", "#E03424", "#008000"]
g = plots.get_subplot_plotter()
g.settings.alpha_factor_contour_lines=contour_alpha
g.settings.line_labels = False

# plot samples
g.triangle_plot(mcsamples, filled=True, markers=markers, contour_colors=contour_colors, colors=colors, param_limits={"h": [0.67, 0.72], "Omega_m": [0.2, 0.37]})

# add horizontal region to plot
g.add_y_bands(0.3353, 0.0091, color="#008000", ax=(1,0), zorder=0.5, alpha1=0.7, alpha2=0.35)

# awful workaround to create custom legend without being attached to axis
# required because the legend for the 1D SNIa (or the horizontal region) isn't showing
class AnyObject:
    pass
class AnyObject2:
    pass
class AnyObject3:
    pass

class AnyObjectHandler:
    def __init__(self, color):
        self.color = color

    def legend_artist(self, legend, orig_handle, fontsize, handlebox):
        x0, y0 = handlebox.xdescent, handlebox.ydescent
        width, height = handlebox.width, handlebox.height
        patch = mpatches.Rectangle([x0, y0], width, height, facecolor=self.color)
        handlebox.add_artist(patch)
        return patch

legends = ["ET", "ET + Pantheon (binned)", "Pantheon (binned)"]
g.fig.legend([AnyObject(), AnyObject2(), AnyObject3()], legends, handler_map={AnyObject: AnyObjectHandler("#006FED"), AnyObject2: AnyObjectHandler("#E03424"), AnyObject3: AnyObjectHandler("#008000")})

# show corner plot
plt.show()

Re: GetDist: Showing 1D constrain on 2D plane

Posted: August 15 2022
by Antony Lewis
For the legend, you could try adding, immediately after (and in the 'else')
https://github.com/cmbant/getdist/blob/master/getdist/plots.py#L1893

the backup code:

Code: Select all

 
 for i, contour in enumerate(lines):
     if contour is None:
         args = self.lines_added.get(i)
         if args:
             args.pop('filled', None)
             lines[i] = matplotlib.lines.Line2D([0, 1], [0, 1], **args)