Completed
Pull Request — master (#559)
by
unknown
01:10
created

_add_logo()   B

Complexity

Conditions 2

Size

Total Lines 39

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
c 0
b 0
f 0
dl 0
loc 39
rs 8.8571
1
# Copyright (c) 2008-2015 MetPy Developers.
2
# Distributed under the terms of the BSD 3-Clause License.
3
# SPDX-License-Identifier: BSD-3-Clause
4
"""Utilities for use in making plots."""
5
6
from datetime import datetime
7
import os
8
9
from matplotlib.collections import LineCollection
10
from matplotlib.pyplot import imread
11
import numpy as np
12
13
from ..units import concatenate
14
15
16
def add_timestamp(ax, time=None, x=0.99, y=-0.04, ha='right', **kwargs):
17
    """Add a timestamp at plot creation time.
18
19
    Adds an ISO format timestamp with the time of plot creation to the plot.
20
21
    Parameters
22
    ----------
23
    ax : `matplotlib.axes.Axes`
24
        The `Axes` instance used for plotting
25
    time : `datetime.datetime`
26
        Specific time to be plotted - datetime.utcnow will be use if not specified
27
    x : float
28
        Relative x position on the axes of the timestamp
29
    y : float
30
        Relative y position on the axes of the timestamp
31
    ha : str
32
        Horizontal alignment of the time stamp string
33
34
    Returns
35
    -------
36
    ax : `matplotlib.axes.Axes`
37
        The `Axes` instance used for plotting
38
39
    """
40
    if not time:
41
        time = datetime.utcnow()
42
    timestr = datetime.strftime(time, 'Created: %Y-%m-%dT%H:%M:%SZ')
43
    ax.text(x, y, timestr, ha=ha, transform=ax.transAxes, **kwargs)
44
    return ax
45
46
47
def _add_logo(fig, x=10, y=25, zorder=100, which='metpy', size='small', **kwargs):
48
    """Add the MetPy or Unidata logo to a figure.
49
50
    Adds an image to the figure.
51
52
    Parameters
53
    ----------
54
    fig : `matplotlib.figure`
55
       The `figure` instance used for plotting
56
    x : int
57
       x position padding in pixels
58
    y : float
59
       y position padding in pixels
60
    zorder : int
61
       The zorder of the logo
62
    which : str
63
       Which logo to plot 'metpy' or 'unidata'
64
    size : str
65
       Size of logo to be used. Can be 'small' for 75 px square or 'large' for
66
       150 px square.
67
68
    Returns
69
    -------
70
    fig : `matplotlib.figure`
71
       The `figure` instance used for plotting
72
73
    """
74
    fname_suffix = {'small': '_75x75.png',
75
                    'large': '_150x150.png'}
76
    fname_prefix = {'unidata': 'unidata',
77
                    'metpy': 'metpy'}
78
    try:
79
        fname = fname_prefix[which] + fname_suffix[size]
80
        logo = imread(os.path.join(os.path.dirname(__file__), '_static', fname))
81
    except KeyError:
82
        raise ValueError('Unknown logo size or selection')
83
84
    fig.figimage(logo, x, y, zorder=zorder, **kwargs)
85
    return fig
86
87
88
def add_metpy_logo(fig, x=10, y=25, zorder=100, size='small', **kwargs):
89
    """Add the MetPy logo to a figure.
90
91
    Adds an image of the MetPy logo to the figure.
92
93
    Parameters
94
    ----------
95
    fig : `matplotlib.figure`
96
       The `figure` instance used for plotting
97
    x : int
98
       x position padding in pixels
99
    y : float
100
       y position padding in pixels
101
    zorder : int
102
       The zorder of the logo
103
    size : str
104
       Size of logo to be used. Can be 'small' for 75 px square or 'large' for
105
       150 px square.
106
107
    Returns
108
    -------
109
    fig : `matplotlib.figure`
110
       The `figure` instance used for plotting
111
112
    """
113
    _add_logo(fig, x=x, y=y, zorder=zorder, which='metpy', size=size, **kwargs)
114
115
116
def add_unidata_logo(fig, x=10, y=25, zorder=100, size='small', **kwargs):
117
    """Add the Unidata logo to a figure.
118
119
    Adds an image of the MetPy logo to the figure.
120
121
    Parameters
122
    ----------
123
    fig : `matplotlib.figure`
124
       The `figure` instance used for plotting
125
    x : int
126
       x position padding in pixels
127
    y : float
128
       y position padding in pixels
129
    zorder : int
130
       The zorder of the logo
131
    size : str
132
       Size of logo to be used. Can be 'small' for 75 px square or 'large' for
133
       150 px square.
134
135
    Returns
136
    -------
137
    fig : `matplotlib.figure`
138
       The `figure` instance used for plotting
139
140
    """
141
    _add_logo(fig, x=x, y=y, zorder=zorder, which='unidata', size=size, **kwargs)
142
143
# Not part of public API
144
def colored_line(x, y, c, **kwargs):
145
    """Create a multi-colored line.
146
147
    Takes a set of points and turns them into a collection of lines colored by another array.
148
149
    Parameters
150
    ----------
151
    x : array-like
152
        x-axis coordinates
153
    y : array-like
154
        y-axis coordinates
155
    c : array-like
156
        values used for color-mapping
157
    kwargs : dict
158
        Other keyword arguments passed to :class:`matplotlib.collections.LineCollection`
159
160
    Returns
161
    -------
162
        The created :class:`matplotlib.collections.LineCollection` instance.
163
164
    """
165
    # Mask out any NaN values
166
    nan_mask = ~(np.isnan(x) | np.isnan(y) | np.isnan(c))
167
    x = x[nan_mask]
168
    y = y[nan_mask]
169
    c = c[nan_mask]
170
171
    # Paste values end to end
172
    points = concatenate([x, y])
173
174
    # Exploit numpy's strides to present a view of these points without copying.
175
    # Dimensions are (segment, start/end, x/y). Since x and y are concatenated back to back,
176
    # moving between segments only moves one item; moving start to end is only an item;
177
    # The move between x any moves from one half of the array to the other
178
    num_pts = points.size // 2
179
    final_shape = (num_pts - 1, 2, 2)
180
    final_strides = (points.itemsize, points.itemsize, num_pts * points.itemsize)
181
    segments = np.lib.stride_tricks.as_strided(points, shape=final_shape,
182
                                               strides=final_strides)
183
184
    # Create a LineCollection from the segments and set it to colormap based on c
185
    lc = LineCollection(segments, **kwargs)
186
    lc.set_array(c)
187
    return lc
188