Skip to content

Commit

Permalink
add plot_4d for x-y-z DD colored scatter plots, with optional animati…
Browse files Browse the repository at this point in the history
…on and video export
  • Loading branch information
cmbant committed Jun 4, 2021
1 parent 7706d37 commit 2cfe557
Show file tree
Hide file tree
Showing 10 changed files with 564 additions and 68 deletions.
2 changes: 1 addition & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ GetDist
:target: https://getdist.readthedocs.org/en/latest
.. image:: https://mybinder.org/badge_logo.svg
:target: https://mybinder.org/v2/gh/cmbant/getdist/master?filepath=docs%2Fplot_gallery.ipynb
.. image:: https://img.shields.io/badge/arXiv-1910.13970-b31b1b.svg
.. image:: https://img.shields.io/badge/arXiv-1910.13970-b31b1b.svg?color=0B6523
:target: https://arxiv.org/abs/1910.13970

Description
Expand Down
172 changes: 154 additions & 18 deletions docs/plot_gallery.html

Large diffs are not rendered by default.

129 changes: 111 additions & 18 deletions docs/plot_gallery.ipynb

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ def setup(app):
]

intersphinx_mapping = {'python': ('https://docs.python.org/3', None),
'numpy': ('https://docs.scipy.org/doc/numpy/', None),
'numpy': ('https://numpy.org/doc/stable/', None),
'scipy': ('https://docs.scipy.org/doc/scipy/reference/', None),
'matplotlib': ('https://matplotlib.org/', None)}

Expand Down
2 changes: 1 addition & 1 deletion getdist/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
__author__ = 'Antony Lewis'
__version__ = "1.2.3"
__version__ = "1.3.0"
__url__ = "https://getdist.readthedocs.io"

from getdist.inifile import IniFile
Expand Down
12 changes: 10 additions & 2 deletions getdist/chains.py
Original file line number Diff line number Diff line change
Expand Up @@ -900,15 +900,23 @@ def thin_indices_single_samples(factor, weights):

return thin_ix

def random_single_samples_indices(self, random_state=None, thin: int = 1):
def random_single_samples_indices(self, random_state=None, thin: Optional[float] = None,
max_samples: Optional[int] = None):
"""
Returns an array of sample indices that give a list of weight-one samples, by randomly
selecting samples depending on the sample weights
:param random_state: random seed or Generator
:param thin: additional integer thinning factor (to get fewer samples)
:param thin: additional thinning factor (>1 to get fewer samples)
:param max_samples: optional parameter to thin to get a specified mean maximum number of samples
:return: array of sample indices
"""
if max_samples is None:
thin = thin or 1
else:
if thin is not None:
raise WeightedSampleError('Cannot set thin and max_samples')
thin = max(1, self.norm / np.max(self.weights) / max_samples)
random_state = np.random.default_rng(random_state)
max_weight = np.max(self.weights)
rand = random_state.random(self.numrows)
Expand Down
8 changes: 6 additions & 2 deletions getdist/gaussian_mixtures.py
Original file line number Diff line number Diff line change
Expand Up @@ -499,12 +499,16 @@ def __init__(self, ndim=4, ncomponent=1, names=None, weights=None, seed=None, la

def randomTestMCSamples(ndim=4, ncomponent=1, nsamp=10009, nMCSamples=1, seed=10, names=None, labels=None):
"""
get a list of MCSamples instances with random samples from random covariances and y
get a MCSamples instance, or list of MCSamples instances with random samples from random covariances and y
"""
if names is None:
names = ["x%s" % i for i in range(ndim)]
if labels is None:
labels = ["x_{%s}" % i for i in range(ndim)]
seed = np.random.default_rng(seed)
return [RandomTestMixtureND(ndim, ncomponent, names, seed=seed).MCSamples(
result = [RandomTestMixtureND(ndim, ncomponent, names, seed=seed).MCSamples(
nsamp, labels=labels, name_tag='Sim %s' % (i + 1), random_state=seed) for i in range(nMCSamples)]
if nMCSamples > 1:
return result
else:
return result[0]
72 changes: 58 additions & 14 deletions getdist/gui/mainwindow.py
Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,16 @@ def _createWidgets(self):
self.comboBoxColor.clear()
self.comboBoxColor.setEnabled(False)

self.toggleZ = QRadioButton("Z-axis:", self.selectWidget)
self.connect(self.toggleZ, SIGNAL("toggled(bool)"), self.statusPlotType)
self.comboBoxZ = QComboBox(self)
self.comboBoxZ.clear()
self.comboBoxZ.setEnabled(False)

self.checkShadow = QCheckBox("Shadows", self.selectWidget)
self.checkShadow.setCheckState(Qt.Unchecked)
self.checkShadow.setVisible(False)

self.toggleFilled.setChecked(True)

self.trianglePlot = QCheckBox("Triangle Plot", self.selectWidget)
Expand Down Expand Up @@ -479,17 +489,24 @@ def h_stack(*items):

leftLayout.addWidget(self.selectAllX, 5, 0, 1, 2)
leftLayout.addWidget(self.selectAllY, 5, 2, 1, 2)
leftLayout.addWidget(self.listParametersX, 6, 0, 5, 2)
leftLayout.addWidget(self.listParametersX, 6, 0, 6, 2)
leftLayout.addWidget(self.listParametersY, 6, 2, 1, 2)

leftLayout.addWidget(self.toggleFilled, 7, 2, 1, 1)
leftLayout.addWidget(self.checkInsideLegend, 7, 3, 1, 1)
leftLayout.addWidget(self.toggleLine, 8, 2, 1, 1)
leftLayout.addWidget(self.checkShade, 8, 3, 1, 1)
leftLayout.addWidget(self.toggleColor, 9, 2, 1, 1)
leftLayout.addWidget(self.comboBoxColor, 9, 3, 1, 1)
leftLayout.addWidget(self.trianglePlot, 10, 2, 1, 2)

leftLayout.addWidget(self.pushButtonPlot, 12, 0, 1, 4)
leftLayout.addWidget(self.toggleZ, 9, 2, 1, 1)
leftLayout.addWidget(self.comboBoxZ, 9, 3, 1, 1)

leftLayout.addWidget(self.toggleColor, 10, 2, 1, 1)
leftLayout.addWidget(self.comboBoxColor, 10, 3, 1, 1)

leftLayout.addWidget(self.trianglePlot, 11, 2, 1, 1)
leftLayout.addWidget(self.checkShadow, 11, 3, 1, 1)

leftLayout.addWidget(self.pushButtonPlot, 13, 0, 1, 4)

self.selectWidget.setLayout(leftLayout)

Expand Down Expand Up @@ -1211,7 +1228,8 @@ def find_new_name(old_names):
self._updateListParametersSelection(old_selection["x"], self.listParametersX)
self._updateListParametersSelection(old_selection["y"], self.listParametersY)

self._updateComboBoxColor(self.paramNames.list())
self._updateComboBoxParam(self.comboBoxColor, self.paramNames.list())
self._updateComboBoxParam(self.comboBoxZ, list(self.paramNamesTags))

def _resetPlotData(self):
# Script
Expand Down Expand Up @@ -1434,6 +1452,9 @@ def getYParams(self):
return [self.paramNamesTags[tag]
for tag in self.getCheckedParams(self.listParametersY)]

def getZParam(self):
return self.paramNamesTags[str(self.comboBoxZ.currentText())]

def statusSelectAllX(self):
"""
Slot function called when selectAllX is modified.
Expand All @@ -1459,7 +1480,11 @@ def statusSelectAllY(self):
def statusPlotType(self, checked):
# radio buttons changed
self.checkShade.setEnabled(self.toggleLine.isChecked())
self.comboBoxColor.setEnabled(self.toggleColor.isChecked())
self.comboBoxColor.setEnabled(self.toggleColor.isChecked() or self.toggleZ.isChecked())
self.comboBoxZ.setEnabled(self.toggleZ.isChecked())
if self.toggleZ.isChecked():
self.trianglePlot.setCheckState(Qt.Unchecked)
self.checkShadow.setVisible(self.toggleZ.isChecked())

def statusTriangle(self, checked):
self.checkInsideLegend.setVisible(
Expand All @@ -1472,16 +1497,16 @@ def itemCheckChange(self, item):
self.trianglePlot.checkState() != Qt.Checked)
self.checkInsideLegend.setEnabled(self.checkInsideLegend.isVisible())

def _updateComboBoxColor(self, listOfParams):
def _updateComboBoxParam(self, combo, listOfParams):
if self.rootdirname and os.path.isdir(self.rootdirname):
param_old = str(self.comboBoxColor.currentText())
param_old = str(combo.currentText())
param_old_new_name = getattr(
self.paramNames.parWithName(param_old), "name", None)
self.comboBoxColor.clear()
self.comboBoxColor.addItems(listOfParams)
idx = self.comboBoxColor.findText(param_old_new_name, Qt.MatchExactly)
combo.clear()
combo.addItems(listOfParams)
idx = combo.findText(param_old_new_name, Qt.MatchExactly)
if idx != -1:
self.comboBoxColor.setCurrentIndex(idx)
combo.setCurrentIndex(idx)

def checkedRootNames(self):
items = []
Expand Down Expand Up @@ -1659,7 +1684,26 @@ def make_space_for_legend():
script += ")\n"
else:
raise GuiSelectionError("Select more than 1 x parameter for triangle plot")

elif self.toggleZ.isChecked():
z_param = self.getZParam()
if len(items_x) == 1 and len(items_y) == 1 and z_param:
params = [items_x[0], items_y[0], z_param]
if color_param:
params.append(color_param)
logging.debug("4d plot with params = %s" % str(params))
script += "params = %s\n" % str(params)
setSizeForN(1, 1)
cols = [c[-1] for c in self.plotter.settings.line_styles[:len(roots) - 1]]
self.plotter.plot_4d(roots, params, color_bar=z_param, compare_colors=cols,
shadow_color=self.checkShadow.isChecked())
script += "g.plot_4d(roots, params, color_bar=True%s%s)\n" % ("" if len(roots) == 1 else
", compare_colors=%r" % cols,
", shadow_color=True" if
self.checkShadow.isChecked() else "")
self.updatePlot()
else:
raise GuiSelectionError("For an x-y-z plot select one parameter of each, and optionally a "
"parameter to color by")
elif len(items_x) > 0 and len(items_y) == 0:
# 1D plot
actionText = "1D plot"
Expand Down
Loading

0 comments on commit 2cfe557

Please sign in to comment.