in python-package/lets_plot/plot/marginal_layer.py [0:0]
def _to_marginal(side: str, size, layer: LayerSpec) -> LayerSpec:
if side not in ['l', 'r', 't', 'b']:
raise ValueError("Invalid 'side' value: {}. Valid values: 'l','r','t','b'.".format(side))
if size is not None:
if not 0.01 <= size <= 0.95:
raise ValueError("Invalid 'size' value: {}. Should be in range [0.01..0.95].".format(size))
layer_copy = LayerSpec.duplicate(layer)
marginal_options = dict(
marginal=True,
margin_side=side,
margin_size=size
)
layer_props = layer_copy.props()
layer_props.update(marginal_options)
layer_kind = None
stat = layer_props.get('stat')
if stat is not None:
if stat == 'bin':
layer_kind = 'histogram'
elif stat == 'ydensity':
layer_kind = 'violin'
elif stat in ('density', 'boxplot', 'boxplot_outlier'):
layer_kind = stat
else:
geom = layer_props.get('geom')
if geom in ('histogram', 'boxplot', 'violin', 'density', 'freqpoly'):
layer_kind = geom
auto_settings = {}
# choose a proper orientation
if (side in ('l', 'r') and layer_kind in ('histogram', 'density', 'freqpoly')):
auto_settings['orientation'] = 'y'
if layer_kind in ('boxplot', 'boxplot_outlier', 'violin'):
if side in ('l', 'r'):
auto_settings['x'] = 0
elif side in ('t', 'b'):
auto_settings['y'] = 0
auto_settings['orientation'] = 'y'
# Update layer's options with auto-generated and try not to override user-defined options.
filtered = {k: v for k, v in layer_props.items() if v is not None}
layer_props.update(
{**auto_settings, **filtered}
)
# For 'histogram' set mapping of x or y to '..density..' for compatibility with 'density' geom.
if layer_kind == 'histogram':
if side in ('l', 'r'):
added_mapping = {'x': '..density..'}
elif side in ('t', 'b'):
added_mapping = {'y': '..density..'}
aes_feature_spec = layer_props.get('mapping')
mappings = aes_feature_spec.props() if isinstance(aes_feature_spec, FeatureSpec) else {}
filtered_mappings = {k: v for k, v in mappings.items() if v is not None}
updated_mappings = {**added_mapping, **filtered_mappings}
updated_aes_feature_spec = FeatureSpec('mapping', name=None, **updated_mappings)
layer_props['mapping'] = updated_aes_feature_spec
return layer_copy