Source code for pylawr.plot.layer.lawr_header
#!/bin/env python
# -*- coding: utf-8 -*-
#
# Created on 04.09.17
#
# Created for pattern
#
#
# Copyright (C) {2017}
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# System modules
import logging
from copy import deepcopy
# External modules
import numpy as np
# Internal modules
from .base import BaseLayer
logger = logging.getLogger(__name__)
[docs]class LawrHeaderLayer(BaseLayer):
"""
A LawrHeaderLayer adds a header layer. This header layer has three
specific area, which can be used (title, left, right):
.. code::
---------------------------------
------------- TITLE -------------
---------------------------------
+++++++++++++++++++++++++++++++++
----------------+----------------
---- LEFT ------+---- RIGHT -----
----------------+----------------
The different areas are splitted by lines. ``left`` and ``right`` are a
dictionary where the entries are display as `key`: `value`. The title can be
set as str.
Parameters
----------
zorder : int
The z-order defines the drawing order of the layers. If no z-order
is set, the z-order will be set during plotting based on layer order
in subplot. Default is 0.
**settings
Variable keyword arguments dict, which is passed during plotting to
every :py:meth:`~matplotlib.axes.Axes.text` call. Title and info box
specific settings can be set with ``title_settings`` and
``info_settings``.
Attributes
----------
zorder : int
The drawing order of this layer. If not set, it will be
automatically determined during plotting by subplot.
settings : dict
The settings for this layer. These settings can be accessed directly
and via a dict like interface of this layer.
title : str
This title is used as title for this header layer.
left : dict(str, str)
This dictionary is plotted to the left information box within this
header. If the order should be preserved, you can also pass an
:py:class:`~collections.OrderedDict`.
right : dict(str, str)
This dictionary is plotted to the right information box within this
header. If the order should be preserved, you can also pass an
:py:class:`~collections.OrderedDict`.
text_padding : float
This padding is used to generate space to the left position of the
text. This is only applied to the information box texts. A positive
value will move the text to the right, while a negative value to the
left.
line_settings : dict
These specific settings are passed to the creation of the lines to
create the three different visually separated boxes. All valid
kwargs of :py:class:`matplotlib.lines.Line2D` except `transform` and
`zorder` can be used.
title_settings : dict
These specific settings are used during creation of the title and
is passed to :py:meth:`~matplotlib.axes.Axes.text`. This settings
dict has a higher priority than the normal settings dict and is used
to update the normal settings dict for the title. All valid kwargs
of :py:class:`matplotlib.text.Text` except `zorder` can be used.
info_settings : dict
These specific settings are used during creation of the left and
right information box and is passed to
:py:meth:`~matplotlib.axes.Axes.text`. These settings have a
higher priority than the normal settings dict and is used to update
the normal settings dict for the title. All valid kwargs of
:py:class:`matplotlib.text.Text` except `zorder` can be used.
"""
def __init__(self, zorder=0, **settings):
super().__init__(zorder, **settings)
self.title = 'title missing'
self.left = {
'left_info': 'every entry will create a new line',
'key_l': 'value_l'
}
self.right = {
'right_info': 'every entry will create a new line',
'key_r': 'value_r'
}
self.text_padding = 0.05
self.line_settings = dict(
color='k', lw=0.5
)
self.title_settings = dict(
va='center', ha='center',
)
self.info_settings = dict(
va='center', ha='left'
)
[docs] def _plot_lines_on_ax(self, ax):
line_horizontal = ax.axhline(y=2/3, xmin=0, xmax=1, zorder=self.zorder,
**self.line_settings)
line_vertical = ax.axvline(x=0.5, ymin=0, ymax=2/3, zorder=self.zorder,
**self.line_settings)
return line_horizontal, line_vertical
[docs] def _plot_text_on_ax(self, ax, x, y, text, **specific_settings):
ax_coords = ax.transAxes
text_settings = deepcopy(self.settings)
text_settings.update(specific_settings)
plotted_text = ax.text(x=x, y=y, s=text, zorder=self.zorder,
transform=ax_coords, **text_settings)
return plotted_text
[docs] def _plot_title_on_ax(self, ax):
text_title = self._plot_text_on_ax(ax=ax, x=0.5, y=5/6, text=self.title,
**self.title_settings)
return text_title
[docs] def _plot_info_box_on_ax(self, ax, info_dict, x_pos,):
y_positions = np.linspace(2/3, 0, len(info_dict)+2)[1:-1]
text_list = []
for text_num, key in enumerate(info_dict.keys()):
text_to_plot = '{0:<5}: {1:<40}'.format(key, info_dict[key])
y_pos = y_positions[text_num]
plotted_text = self._plot_text_on_ax(
ax=ax, x=x_pos, y=y_pos, text=text_to_plot, **self.info_settings
)
text_list.append(plotted_text)
return text_list
[docs] def plot(self, ax):
"""
This header layer is plotted on given axes. The lines are plotted
firstly, while texts are plotted afterwards. All are plotted with
set zorder on axes.
Parameters
----------
ax : :py:class:`matplotlib.axes.Axes`
The header is plotted with set zorder on this subplot.
"""
line_h, line_v = self._plot_lines_on_ax(ax=ax)
text_title = self._plot_title_on_ax(ax=ax)
text_left_list = self._plot_info_box_on_ax(ax=ax, info_dict=self.left,
x_pos=0+self.text_padding)
text_right_list = self._plot_info_box_on_ax(ax=ax, info_dict=self.right,
x_pos=0.5+self.text_padding)
self._collection.append(line_h)
self._collection.append(line_v)
self._collection.append(text_title)
self._collection.extend(text_left_list)
self._collection.extend(text_right_list)