Commit 68823ce1 authored by Theo Steininger's avatar Theo Steininger
Browse files

Merge branch 'space_docstrings' into 'master'

Space docstrings

See merge request !83
parents b4b74105 d1bb1965
Pipeline #12141 passed with stage
in 6 minutes and 11 seconds
from descriptors import *
from plots import *
from figures import *
from colormap import *
\ No newline at end of file
from colormap import Colormap
import colormaps
\ No newline at end of file
from nifty.plotting.plotly_wrapper import PlotlyWrapper
class Colormap(PlotlyWrapper):
def __init__(self, name, red, green, blue):
self.name = name
self.red = red
self.green = green
self.blue = blue
def validate_map(self):
def validade(m):
#TODO: implement validation
pass
@staticmethod
def from_matplotlib_colormap_internal(name, mpl_cmap): # no discontinuities only
red = [(c[0], c[2]) for c in mpl_cmap['red']]
green = [(c[0], c[2]) for c in mpl_cmap['green']]
blue = [(c[0], c[2]) for c in mpl_cmap['blue']]
return Colormap(name, red, green, blue)
def to_plotly(self):
r, g, b = 0, 0, 0
converted = list()
prev_split, prev_r, prev_g, prev_b = 0., 0., 0., 0.
while prev_split < 1:
next_split = min(self.red[r][0], self.blue[b][0], self.green[g][0])
if next_split == self.red[r][0]:
red_val = self.red[r][1]
r += 1
else:
slope = (self.red[r][1]-prev_r) / (self.red[r][0] - prev_split)
y = prev_r - slope * prev_split
red_val = slope * next_split + y
if next_split == self.green[g][0]:
green_val = self.green[g][1]
g += 1
else:
slope = (self.green[g][1] - prev_g) / (self.green[g][0] - prev_split)
y = prev_g - slope * prev_split
green_val = slope * next_split + y
if next_split == self.blue[b][0]:
blue_val = self.blue[b][1]
b += 1
else:
slope = (self.blue[b][1] - prev_b) / (self.blue[b][0] - prev_split)
y = prev_r - slope * prev_split
blue_val = slope * next_split + y
prev_split, prev_r, prev_g, prev_b = next_split, red_val, green_val, blue_val
converted.append([next_split,
'rgb(' +
str(int(red_val*255)) + "," +
str(int(green_val*255)) + "," +
str(int(blue_val*255)) + ")"])
return converted
from nifty.plotting.colormap.colormap import Colormap
def HighEnergyCmap():
"""
Returns a color map often used in High Energy Astronomy.
"""
red = [(0.0, 0.0),
(0.167, 0.0),
(0.333, 0.5),
(0.5, 1.0),
(0.667, 1.0),
(0.833, 1.0),
(1.0, 1.0)]
green = [(0.0, 0.0),
(0.167, 0.0),
(0.333, 0.0),
(0.5, 0.0),
(0.667, 0.5),
(0.833, 1.0),
(1.0, 1.0)]
blue = [(0.0, 0.0),
(0.167, 1.0),
(0.333, 0.5),
(0.5, 0.0),
(0.667, 0.0),
(0.833, 0.0),
(1.0, 1.0)]
return Colormap("High Energy", red, green, blue)
def FaradayMapCmap():
"""
Returns a color map used in reconstruction of the "Faraday Map".
References
----------
.. [#] N. Opermann et. al.,
"An improved map of the Galactic Faraday sky",
Astronomy & Astrophysics, Volume 542, id.A93, 06/2012;
`arXiv:1111.6186 <http://www.arxiv.org/abs/1111.6186>`_
"""
red = [(0.0, 0.35),
(0.1, 0.4),
(0.2, 0.25),
(0.41, 0.47),
(0.5, 0.8),
(0.56, 0.96),
(0.59, 1.0),
(0.74, 0.8),
(0.8, 0.8),
(0.9, 0.5),
(1.0, 0.4)]
green = [(0.0, 0.0),
(0.2, 0.0),
(0.362, 0.88),
(0.5, 1.0),
(0.638, 0.88),
(0.8, 0.25),
(0.9, 0.3),
(1.0, 0.2)]
blue = [(0.0, 0.35),
(0.1, 0.4),
(0.2, 0.8),
(0.26, 0.8),
(0.41, 1.0),
(0.44, 0.96),
(0.5, 0.8),
(0.59, 0.47),
(0.8, 0.0),
(1.0, 0.0)]
return Colormap("Faraday Map", red, green, blue)
def FaradayUncertaintyCmap():
"""
Returns a color map used for the "Faraday Map Uncertainty".
References
----------
.. [#] N. Opermann et. al.,
"An improved map of the Galactic Faraday sky",
Astronomy & Astrophysics, Volume 542, id.A93, 06/2012;
`arXiv:1111.6186 <http://www.arxiv.org/abs/1111.6186>`_
"""
red = [(0.0, 1.0),
(0.1, 0.8),
(0.2, 0.65),
(0.41, 0.6),
(0.5, 0.7),
(0.56, 0.96),
(0.59, 1.0),
(0.74, 0.8),
(0.8, 0.8),
(0.9, 0.5),
(1.0, 0.4)]
green = [(0.0, 0.9),
(0.2, 0.65),
(0.362, 0.95),
(0.5, 1.0),
(0.638, 0.88),
(0.8, 0.25),
(0.9, 0.3),
(1.0, 0.2)]
blue = [(0.0, 1.0),
(0.1, 0.8),
(0.2, 1.0),
(0.41, 1.0),
(0.44, 0.96),
(0.5, 0.7),
(0.59, 0.42),
(0.8, 0.0),
(1.0, 0.0)]
return Colormap("Faraday Uncertainty", red, green, blue)
def PlusMinusCmap():
"""
Returns a color map useful for a zero-centerd range of values.
"""
red = [(0.0, 1.0),
(0.1, 0.96),
(0.2, 0.84),
(0.3, 0.64),
(0.4, 0.36),
(0.5, 0.0),
(0.6, 0.0),
(0.7, 0.0),
(0.8, 0.0),
(0.9, 0.0),
(1.0, 0.0)]
green = [(0.0, 0.5),
(0.1, 0.32),
(0.2, 0.18),
(0.3, 0.08),
(0.4, 0.02),
(0.5, 0.0),
(0.6, 0.02),
(0.7, 0.08),
(0.8, 0.18),
(0.9, 0.32),
(1.0, 0.5)]
blue = [(0.0, 0.0),
(0.1, 0.0),
(0.2, 0.0),
(0.3, 0.0),
(0.4, 0.0),
(0.5, 0.0),
(0.6, 0.36),
(0.7, 0.64),
(0.8, 0.84),
(0.9, 0.96),
(1.0, 1.0)]
return Colormap("Plus Minus", red, green, blue)
def PlankCmap():
"""
Returns a color map similar to the one used for the "Planck CMB Map".
"""
red = [(0.0, 0.0),
(0.1, 0.0),
(0.2, 0.0),
(0.3, 0.0),
(0.4, 0.0),
(0.5, 1.0),
(0.6, 1.0),
(0.7, 1.0),
(0.8, 0.83),
(0.9, 0.67),
(1.0, 0.5)]
green = [(0.0, 0.0),
(0.1, 0.0),
(0.2, 0.0),
(0.3, 0.3),
(0.4, 0.7),
(0.5, 1.0),
(0.6, 0.7),
(0.7, 0.3),
(0.8, 0.0),
(0.9, 0.0),
(1.0, 0.0)]
blue = [(0.0, 0.5),
(0.1, 0.67),
(0.2, 0.83),
(0.3, 1.0),
(0.4, 1.0),
(0.5, 1.0),
(0.6, 0.0),
(0.7, 0.0),
(0.8, 0.0),
(0.9, 0.0),
(1.0, 0.0)]
return Colormap("Planck-like", red, green, blue)
......@@ -7,6 +7,7 @@ from nifty.plotting.plots import Heatmap, Mollweide
class Figure2D(FigureFromPlot):
def __init__(self, plots, title=None, width=None, height=None,
xaxis=None, yaxis=None):
super(Figure2D, self).__init__(plots, title, width, height)
# TODO: add sanitization of plots input
if isinstance(plots[0], Heatmap) and not width and not height:
......@@ -45,7 +46,7 @@ class Figure2D(FigureFromPlot):
showticklabels=False
)
if self.yaxis:
plotly_object['layout']['yaxis'] = self.yaxis._to_plotly()
plotly_object['layout']['yaxis'] = self.yaxis.to_plotly()
elif not self.yaxis:
plotly_object['layout']['yaxis'] = dict(showline=False)
......
# -*- coding: utf-8 -*-
from abc import abstractmethod
from nifty.plotting.plotly_wrapper import PlotlyWrapper
......@@ -8,3 +10,7 @@ class FigureBase(PlotlyWrapper):
self.title = title
self.width = width
self.height = height
@abstractmethod
def to_plotly(self):
raise NotImplementedError
......@@ -2,7 +2,6 @@
# -*- coding: utf-8 -*-
from abc import abstractmethod
from figure_base import FigureBase
......@@ -11,7 +10,6 @@ class FigureFromPlot(FigureBase):
super(FigureFromPlot, self).__init__(title, width, height)
self.plots = plots
@abstractmethod
def to_plotly(self):
data = [plt.to_plotly() for plt in self.plots]
layout = {'title': self.title,
......
# -*- coding: utf-8 -*-
import numpy as np
from nifty import dependency_injector as gdi
from figure_base import FigureBase
from figure_3D import Figure3D
plotly = gdi.get('plotly')
# TODO: add nice height and width defaults for multifigure
class MultiFigure(FigureBase):
def __init__(self, rows, columns, subfigures=None,
title=None, width=None, height=None):
def __init__(self, rows, columns, title=None, width=None, height=None,
subfigures=None):
if 'plotly' not in gdi:
raise ImportError("The module plotly is needed but not available.")
super(MultiFigure, self).__init__(title, width, height)
......@@ -31,43 +30,30 @@ class MultiFigure(FigureBase):
self.subfigures[row, column] = figure
def to_plotly(self):
sub_titles = self.subfigures.copy()
sub_titles = sub_titles.flatten
title_extractor = lambda z: z.title
sub_titles = np.vectorize(title_extractor)(sub_titles)
title_extractor = lambda z: z.title if z else ""
sub_titles = \
tuple(np.vectorize(title_extractor)(self.subfigures.flatten()))
sub_specs = self.subfigures.copy_empty()
specs_setter = \
lambda z: {'is_3d': True} if isinstance(z, Figure3D) else {}
sub_specs = np.vectorize(specs_setter)(sub_specs)
sub_specs = \
list(map(list, np.vectorize(specs_setter)(self.subfigures)))
multi_figure_plotly_object = plotly.tools.make_subplots(
self.rows,
self.columns,
subplot_titles=sub_titles,
specs=sub_specs)
# TODO resolve bug with titles and 3D subplots
for index, fig in np.ndenumerate(self.subfigures):
for plot in fig.plots:
multi_figure_plotly_object.append_trace(plot.to_plotly(),
index[0]+1,
index[1]+1)
if fig:
for plot in fig.plots:
multi_figure_plotly_object.append_trace(plot.to_plotly(),
index[0]+1,
index[1]+1)
multi_figure_plotly_object['layout'].update(height=self.height,
width=self.width,
title=self.title)
return multi_figure_plotly_object
@staticmethod
def from_figures_2cols(figures, title=None, width=None, height=None):
multi_figure = MultiFigure((len(figures)+1)/2, 2, title, width, height)
for i in range(0, len(figures), 2):
multi_figure.add_subfigure(figures[i], i/2, 0)
for i in range(1, len(figures), 2):
multi_figure.add_subfigure(figures[i], i/2, 1)
return multi_figure
return multi_figure_plotly_object
# -*- coding: utf-8 -*-
from nifty.plotting.plots.plot import Plot
from nifty.plotting.plotly_wrapper import PlotlyWrapper
class Heatmap(Plot):
def __init__(self, data, label='', line=None, marker=None, webgl=False,
class Heatmap(PlotlyWrapper):
def __init__(self, data, color_map=None, webgl=False,
smoothing=False): # smoothing 'best', 'fast', False
super(Heatmap, self).__init__(label, line, marker)
self.data = data
self.color_map = color_map
self.webgl = webgl
self.smoothing = smoothing
def to_plotly(self):
plotly_object = super(Heatmap, self).to_plotly()
plotly_object = dict()
plotly_object['z'] = self.data
plotly_object['showscale'] = False
if self.color_map:
plotly_object['colorscale'] = self.color_map.to_plotly()
plotly_object['colorbar'] = dict(title=self.color_map.name, x=0.42)
if self.webgl:
plotly_object['type'] = 'heatmapgl'
else:
......
......@@ -8,7 +8,7 @@ healpy = gdi.get('healpy')
class Mollweide(Heatmap):
def __init__(self, data, label='', line=None, marker=None, webgl=False,
def __init__(self, data, color_map=None, webgl=False,
smoothing=False): # smoothing 'best', 'fast', False
if 'pylab' not in gdi:
raise ImportError("The module pylab is needed but not available.")
......@@ -16,8 +16,7 @@ class Mollweide(Heatmap):
raise ImportError("The module healpy is needed but not available.")
data = self._mollview(data)
super(Mollweide, self).__init__(data, label, line, marker, webgl,
smoothing)
super(Mollweide, self).__init__(data, color_map, webgl, smoothing)
def _mollview(self, x, xsize=800):
x = healpy.pixelfunc.ma_to_array(x)
......
# -*- coding: utf-8 -*-
from abc import abstractmethod
from nifty.plotting.plots.plot import Plot
from scatter_plot import ScatterPlot
class Cartesian(Plot):
class Cartesian(ScatterPlot):
def __init__(self, x, y, label, line, marker):
super(Cartesian, self).__init__(label, line, marker)
self.x = x
......
from nifty.plotting.plots.plot import Plot
from scatter_plot import ScatterPlot
class Geo(Plot):
class Geo(ScatterPlot):
def __init__(self, lon, lat, label='', line=None, marker=None,
proj='mollweide'):
"""
......
......@@ -2,13 +2,16 @@
from abc import abstractmethod
from nifty.plotting.plotly_wrapper import PlotlyWrapper
from nifty.plotting.descriptors import Marker
class Plot(PlotlyWrapper):
class ScatterPlot(PlotlyWrapper):
def __init__(self, label, line, marker):
self.label = label
self.line = line
self.marker = marker
if not self.line and not self.marker:
self.marker = Marker()
@abstractmethod
def to_plotly(self):
......@@ -19,10 +22,10 @@ class Plot(PlotlyWrapper):
ply_object['line'] = self.line.to_plotly()
ply_object['marker'] = self.marker.to_plotly()
elif self.line:
ply_object['mode'] = 'markers'
ply_object['mode'] = 'line'
ply_object['line'] = self.line.to_plotly()
elif self.marker:
ply_object['mode'] = 'line'
ply_object['mode'] = 'markers'
ply_object['marker'] = self.marker.to_plotly()
return ply_object
......@@ -43,8 +43,8 @@ class GLSpace(Space):
----------
nlat : int
Number of latitudinal bins, or rings.
nlon : int, *optional*
Number of longitudinal bins (default: ``2*nlat - 1``).
nlon : int
Number of longitudinal bins.
See Also
--------
......@@ -83,6 +83,8 @@ class GLSpace(Space):
------
ValueError
If input `nlat` is invalid.
ImportError
If the pyHealpix module is not available
"""
if 'pyHealpix' not in gdi:
......
......@@ -60,7 +60,7 @@ class HPSpace(Space):
def __init__(self, nside):
"""
Sets the attributes for a hp_space class instance.
Sets the attributes for a HPSpace class instance.
Parameters
----------
......
......@@ -43,19 +43,17 @@ class LMSpace(Space):
Maximum :math:`\ell`-value up to which the spherical harmonics
coefficients are to be used.
Notes:
------
This implementation implicitly sets the mmax parameter to lmax.
See Also
--------
hp_space : A class for the HEALPix discretization of the sphere [#]_.
gl_space : A class for the Gauss-Legendre discretization of the
sphere [#]_.
Notes
-----
Hermitian symmetry, i.e. :math:`a_{\ell -m} = \overline{a}_{\ell m}` is
always assumed for the spherical harmonics components, i.e. only fields
on the two-sphere with real-valued representations in position space
can be handled.
References
----------
.. [#] K.M. Gorski et al., 2005, "HEALPix: A Framework for
......
......@@ -52,31 +52,37 @@ class RGSpace(Space):
----------
harmonic : bool
Whether or not the grid represents a Fourier basis.
zerocenter : {bool, numpy.ndarray}, *optional*
zerocenter : {bool, numpy.ndarray}
Whether the Fourier zero-mode is located in the center of the grid
(or the center of each axis speparately) or not (default: True).
distances : {float, numpy.ndarray}, *optional*
(or the center of each axis speparately) or not.
MR FIXME: this also does something if the space is not harmonic!
distances : {float, numpy.ndarray}
Distance between two grid points along each axis (default: None).
"""
# ---Overwritten properties and methods---
def __init__(self, shape=(1,), zerocenter=False, distances=None,
def __init__(self, shape, zerocenter=False, distances=None,
harmonic=False):
"""
Sets the attributes for an rg_space class instance.
Sets the attributes for an RGSpace class instance.
Parameters