|
2 | 2 | Plotting datetime charts
|
3 | 3 | ========================
|
4 | 4 |
|
5 |
| -PyGMT accepts a variety of datetime objects to plot data and create charts. |
6 |
| -Aside from the built-in Python ``datetime`` module, PyGMT supports inputs |
7 |
| -containing ISO formatted strings as well as objects generated with |
8 |
| -``numpy``, ``pandas``, and ``xarray``. These data types can be used to plot |
9 |
| -specific points as well as get passed into the ``region`` parameter to |
10 |
| -create a range of the data on an axis. |
11 |
| -
|
12 |
| -The following examples will demonstrate how to create plots using these |
13 |
| -different datetime objects. |
| 5 | +PyGMT accepts a variety of datetime objects to plot data and create charts. Aside from |
| 6 | +the built-in Python ``datetime`` module, PyGMT supports inputs containing ISO formatted |
| 7 | +strings as well as objects generated with ``numpy``, ``pandas``, and ``xarray``. These |
| 8 | +data types can be used to plot specific points as well as get passed into the ``region`` |
| 9 | +parameter to create a range of the data on an axis. |
| 10 | +
|
| 11 | +The following examples will demonstrate how to create plots using these different |
| 12 | +datetime objects. |
14 | 13 | """
|
15 | 14 |
|
16 | 15 | # %%
|
|
25 | 24 | # Using Python's ``datetime``
|
26 | 25 | # ---------------------------
|
27 | 26 | #
|
28 |
| -# In this example, Python's built-in ``datetime`` module is used to create |
29 |
| -# data points stored in the list ``x``. Additionally, dates are passed into |
30 |
| -# the ``region`` parameter in the format ``[x_start, x_end, y_start, y_end]``, |
31 |
| -# where the date range is plotted on the x-axis. An additional notable |
32 |
| -# parameter is ``style``, where it's specified that data points are plotted |
33 |
| -# as circles with a diameter of 0.3 centimeters. |
| 27 | +# In this example, Python's built-in ``datetime`` module is used to create data points |
| 28 | +# stored in the list ``x``. Additionally, dates are passed into the ``region`` parameter |
| 29 | +# in the format ``[x_start, x_end, y_start, y_end]``, where the date range is plotted on |
| 30 | +# the x-axis. An additional notable parameter is ``style``, where it's specified that |
| 31 | +# data points are plotted as circles with a diameter of 0.3 centimeters. |
34 | 32 |
|
35 | 33 | x = [
|
36 | 34 | datetime.date(2010, 6, 1),
|
|
53 | 51 | fig.show()
|
54 | 52 |
|
55 | 53 | # %%
|
56 |
| -# In addition to specifying the date, ``datetime`` supports the time at |
57 |
| -# which the data points were recorded. Using :meth:`datetime.datetime` the |
58 |
| -# ``region`` parameter as well as data points can be created with both date and |
59 |
| -# time information. |
| 54 | +# In addition to specifying the date, ``datetime`` supports the time at which the data |
| 55 | +# points were recorded. Using :meth:`datetime.datetime` the ``region`` parameter as well |
| 56 | +# as data points can be created with both date and time information. |
60 | 57 | #
|
61 | 58 | # Some notable differences to the previous example include:
|
62 | 59 | #
|
63 |
| -# - Modifying ``frame`` to only include West (left) and South (bottom) borders, |
64 |
| -# and removing grid lines |
65 |
| -# - Using circles to plot data points defined by ``c`` in the argument passed |
66 |
| -# through the ``style`` parameter |
| 60 | +# - Modifying ``frame`` to only include West (left) and South (bottom) borders, and |
| 61 | +# removing grid lines |
| 62 | +# - Using circles to plot data points defined by ``c`` in the argument passed through |
| 63 | +# the ``style`` parameter |
67 | 64 |
|
68 | 65 | x = [
|
69 | 66 | datetime.datetime(2021, 1, 1, 3, 45, 1),
|
|
96 | 93 | # Using ISO Format
|
97 | 94 | # ----------------
|
98 | 95 | #
|
99 |
| -# In addition to Python's ``datetime`` module, PyGMT also supports passing |
100 |
| -# dates in ISO format. Basic ISO strings are formatted as ``YYYY-MM-DD`` with |
101 |
| -# each ``-`` delineated section marking the four-digit year value, two-digit |
102 |
| -# month value, and two-digit day value, respectively. |
| 96 | +# In addition to Python's ``datetime`` module, PyGMT also supports passing dates in ISO |
| 97 | +# format. Basic ISO strings are formatted as ``YYYY-MM-DD`` with each ``-`` delineated |
| 98 | +# section marking the four-digit year value, two-digit month value, and two-digit day |
| 99 | +# value, respectively. |
103 | 100 | #
|
104 |
| -# For including the time into an ISO string, the ``T`` character is used, as it |
105 |
| -# can be seen in the following example. This character is immediately followed |
106 |
| -# by a string formatted as ``hh:mm:ss`` where each ``:`` delineated section |
107 |
| -# marking the two-digit hour value, two-digit minute value, and two-digit |
108 |
| -# second value, respectively. The figure in the following example is plotted |
109 |
| -# over a horizontal range of one year from 2016-01-01 to 2017-01-01. |
| 101 | +# For including the time into an ISO string, the ``T`` character is used, as it can be |
| 102 | +# seen in the following example. This character is immediately followed by a string |
| 103 | +# formatted as ``hh:mm:ss`` where each ``:`` delineated section marking the two-digit |
| 104 | +# hour value, two-digit minute value, and two-digit second value, respectively. The |
| 105 | +# figure in the following example is plotted over a horizontal range of one year from |
| 106 | +# 2016-01-01 to 2017-01-01. |
110 | 107 |
|
111 | 108 | x = ["2016-02-01", "2016-06-04T14", "2016-10-04T00:00:15", "2016-12-01T05:00:15"]
|
112 | 109 | y = [1, 3, 5, 2]
|
| 110 | + |
113 | 111 | fig = pygmt.Figure()
|
114 | 112 | fig.plot(
|
115 | 113 | projection="X10c/5c",
|
|
126 | 124 | # %%
|
127 | 125 | # .. note::
|
128 | 126 | #
|
129 |
| -# PyGMT doesn't recognize non-ISO datetime strings like "Jun 05, 2018". If |
130 |
| -# your data contain non-ISO datetime strings, you can convert them to a |
131 |
| -# recognized format using :func:`pandas.to_datetime` and then pass it to |
132 |
| -# PyGMT. |
| 127 | +# PyGMT doesn't recognize non-ISO datetime strings like "Jun 05, 2018". If your data |
| 128 | +# contain non-ISO datetime strings, you can convert them to a recognized format |
| 129 | +# using :func:`pandas.to_datetime` and then pass it to PyGMT. |
133 | 130 |
|
134 | 131 |
|
135 | 132 | # %%
|
136 | 133 | # Mixing and matching Python ``datetime`` and ISO dates
|
137 | 134 | # -----------------------------------------------------
|
138 | 135 | #
|
139 |
| -# The following example provides context on how both ``datetime`` and ISO date |
140 |
| -# data can be plotted using PyGMT. This can be helpful when dates and times are |
141 |
| -# coming from different sources, meaning conversions do not need to take place |
142 |
| -# between ISO and datetime in order to create valid plots. |
| 136 | +# The following example provides context on how both ``datetime`` and ISO date data can |
| 137 | +# be plotted using PyGMT. This can be helpful when dates and times are coming from |
| 138 | +# different sources, meaning conversions do not need to take place between ISO and |
| 139 | +# datetime in order to create valid plots. |
143 | 140 |
|
144 | 141 | x = ["2020-02-01", "2020-06-04", "2020-10-04", datetime.datetime(2021, 1, 15)]
|
145 | 142 | y = [1.3, 2.2, 4.1, 3]
|
| 143 | + |
146 | 144 | fig = pygmt.Figure()
|
147 | 145 | fig.plot(
|
148 | 146 | projection="X10c/5c",
|
|
162 | 160 | # -------------------------------
|
163 | 161 | #
|
164 | 162 | # In the following example, :func:`pandas.date_range` produces a list of
|
165 |
| -# :class:`pandas.DatetimeIndex` objects, which is used to pass date data to |
166 |
| -# the PyGMT figure. |
167 |
| -# Specifically ``x`` contains 7 different :class:`pandas.DatetimeIndex` |
168 |
| -# objects, with the number being manipulated by the ``periods`` parameter. Each |
169 |
| -# period begins at the start of a business quarter as denoted by BQS when |
170 |
| -# passed to the ``freq`` parameter. The initial date is the first argument |
171 |
| -# that is passed to :func:`pandas.date_range` and it marks the first data point |
172 |
| -# in the list ``x`` that will be plotted. |
| 163 | +# :class:`pandas.DatetimeIndex` objects, which is used to pass date data to the PyGMT |
| 164 | +# figure. Specifically ``x`` contains 7 different :class:`pandas.DatetimeIndex` objects, |
| 165 | +# with the number being manipulated by the ``periods`` parameter. Each period begins at |
| 166 | +# the start of a business quarter as denoted by BQS when passed to the ``freq`` |
| 167 | +# parameter. The initial date is the first argument that is passed to |
| 168 | +# :func:`pandas.date_range` and it marks the first data point in the list ``x`` that |
| 169 | +# will be plotted. |
173 | 170 |
|
174 | 171 | x = pd.date_range("2018-03-01", periods=7, freq="BQS")
|
175 | 172 | y = [4, 5, 6, 8, 6, 3, 5]
|
|
192 | 189 | # Using :class:`xarray.DataArray`
|
193 | 190 | # -------------------------------
|
194 | 191 | #
|
195 |
| -# In this example, instead of using a list of :class:`pandas.DatetimeIndex` |
196 |
| -# objects, ``x`` is initialized as an :class:`xarray.DataArray` object. This |
197 |
| -# object provides a wrapper around regular PyData formats. It also allows the |
198 |
| -# data to have labeled dimensions while supporting operations that use various |
199 |
| -# pieces of metadata. The following code uses :func:`pandas.date_range` to fill |
200 |
| -# the DataArray with data, but this is not essential for the creation of a |
201 |
| -# valid DataArray. |
| 192 | +# In this example, instead of using a list of :class:`pandas.DatetimeIndex` objects, |
| 193 | +# ``x`` is initialized as an :class:`xarray.DataArray` object. This object provides a |
| 194 | +# wrapper around regular PyData formats. It also allows the data to have labeled |
| 195 | +# dimensions while supporting operations that use various pieces of metadata. The |
| 196 | +# following code uses :func:`pandas.date_range` to fill the DataArray with data, but |
| 197 | +# this is not essential for the creation of a valid DataArray. |
202 | 198 |
|
203 | 199 | x = xr.DataArray(data=pd.date_range(start="2020-01-01", periods=4, freq="Q"))
|
204 | 200 | y = [4, 7, 5, 6]
|
|
221 | 217 | # Using :class:`numpy.datetime64`
|
222 | 218 | # -------------------------------
|
223 | 219 | #
|
224 |
| -# In this example, instead of using :func:`pd.date_range`, ``x`` is |
225 |
| -# initialized as an ``np.array`` object. Similar to :class:`xarray.DataArray` |
226 |
| -# this wraps the dataset before passing it as an argument. However, |
227 |
| -# ``np.array`` objects use less memory and allow developers to specify |
228 |
| -# data types. |
| 220 | +# In this example, instead of using :func:`pd.date_range`, ``x`` is initialized as an |
| 221 | +# ``np.array`` object. Similar to :class:`xarray.DataArray` this wraps the dataset |
| 222 | +# before passing it as an argument. However, ``np.array`` objects use less memory and |
| 223 | +# allow developers to specify data types. |
229 | 224 |
|
230 | 225 | x = np.array(["2010-06-01", "2011-06-01T12", "2012-01-01T12:34:56"], dtype="datetime64")
|
231 | 226 | y = [2, 7, 5]
|
|
248 | 243 | # Generating an automatic region
|
249 | 244 | # ------------------------------
|
250 | 245 | #
|
251 |
| -# Another way of creating charts involving datetime data can be done by |
252 |
| -# automatically generating the region of the plot. This can be done by |
253 |
| -# passing the DataFrame to :func:`pygmt.info`, which will find the maximum and |
254 |
| -# minimum values for each column and create a list that could be passed as |
255 |
| -# region. Additionally, the ``spacing`` parameter can be used to increase the |
256 |
| -# range past the maximum and minimum data points. |
| 246 | +# Another way of creating charts involving datetime data can be done by automatically |
| 247 | +# generating the region of the plot. This can be done by passing the DataFrame to |
| 248 | +# :func:`pygmt.info`, which will find the maximum and minimum values for each column and |
| 249 | +# create a list that could be passed as region. Additionally, the ``spacing`` parameter |
| 250 | +# can be used to increase the range past the maximum and minimum data points. |
257 | 251 |
|
258 | 252 | data = [
|
259 | 253 | ["20200712", 1000],
|
|
266 | 260 | ]
|
267 | 261 | df = pd.DataFrame(data, columns=["Date", "Score"])
|
268 | 262 | df.Date = pd.to_datetime(df["Date"], format="%Y%m%d")
|
269 |
| - |
270 |
| -fig = pygmt.Figure() |
271 | 263 | region = pygmt.info(
|
272 | 264 | data=df[["Date", "Score"]], per_column=True, spacing=(700, 700), coltypes="T"
|
273 | 265 | )
|
274 | 266 |
|
| 267 | +fig = pygmt.Figure() |
275 | 268 | fig.plot(
|
276 | 269 | region=region,
|
277 | 270 | projection="X15c/10c",
|
|
282 | 275 | pen="1p",
|
283 | 276 | fill="green3",
|
284 | 277 | )
|
285 |
| - |
286 | 278 | fig.show()
|
287 | 279 |
|
288 | 280 |
|
289 | 281 | # %%
|
290 | 282 | # Setting Primary and Secondary Time Axes
|
291 | 283 | # ---------------------------------------
|
292 | 284 | #
|
293 |
| -# This example focuses on annotating the axes and setting the interval in which |
294 |
| -# the annotations should appear. All of these modifications are passed |
295 |
| -# to the ``frame`` parameter and each item in that list modifies a specific |
296 |
| -# aspect of the frame. |
| 285 | +# This example focuses on annotating the axes and setting the interval in which the |
| 286 | +# annotations should appear. All of these modifications are passed to the ``frame`` |
| 287 | +# parameter and each item in that list modifies a specific aspect of the frame. |
297 | 288 | #
|
298 |
| -# Adding ``"WS"`` means that only the Western/Left (**W**) and Southern/Bottom |
299 |
| -# (**S**) borders of the plot are annotated. For more information on this, |
300 |
| -# please refer to the :doc:`Frames, ticks, titles, and labels tutorial |
301 |
| -# </tutorials/basics/frames>`. |
| 289 | +# Adding ``"WS"`` means that only the Western/Left (**W**) and Southern/Bottom (**S**) |
| 290 | +# borders of the plot are annotated. For more information on this, please refer to the |
| 291 | +# :doc:`Frames, ticks, titles, and labels tutorial </tutorials/basics/frames>`. |
302 | 292 | #
|
303 |
| -# Another important item in the list passed to ``frame`` is ``"sxa1Of1D"``. |
304 |
| -# This string modifies the secondary annotation (**s**) of the x-axis (**x**). |
305 |
| -# Specifically, it sets the main annotation and major tick spacing interval |
306 |
| -# to one month (**a1O**) (capital letter O, not zero). Additionally, it sets |
307 |
| -# the minor tick spacing interval to 1 day (**f1D**). To use the month's name |
308 |
| -# instead of its number set :gmt-term:`FORMAT_DATE_MAP` to **o**. More |
309 |
| -# information on configuring date formats can be found at |
| 293 | +# Another important item in the list passed to ``frame`` is ``"sxa1Of1D"``. This string |
| 294 | +# modifies the secondary annotation (**s**) of the x-axis (**x**). Specifically, it sets |
| 295 | +# the main annotation and major tick spacing interval to one month (**a1O**) (capital |
| 296 | +# letter O, not zero). Additionally, it sets the minor tick spacing interval to 1 day |
| 297 | +# (**f1D**). To use the month name instead of its number set :gmt-term:`FORMAT_DATE_MAP` |
| 298 | +# to **o**. More information on configuring date formats can be found at |
310 | 299 | # :gmt-term:`FORMAT_DATE_MAP`, :gmt-term:`FORMAT_DATE_IN`, and
|
311 | 300 | # :gmt-term:`FORMAT_DATE_OUT`.
|
312 | 301 |
|
|
325 | 314 | pen="1p",
|
326 | 315 | fill="green3",
|
327 | 316 | )
|
328 |
| - |
329 | 317 | fig.show()
|
330 | 318 |
|
331 | 319 | # %%
|
332 |
| -# The same concept shown above can be applied to smaller as well as larger |
333 |
| -# intervals. In this example, data are plotted for different times throughout |
334 |
| -# two days. The primary x-axis annotations are modified to repeat every 6 |
335 |
| -# hours, and the secondary x-axis annotations repeat every day and show the |
336 |
| -# day of the week. |
| 320 | +# The same concept shown above can be applied to smaller as well as larger intervals. In |
| 321 | +# this example, data are plotted for different times throughout two days. The primary |
| 322 | +# x-axis annotations are modified to repeat every 6 hours, and the secondary x-axis |
| 323 | +# annotations repeat every day and show the day of the week. |
337 | 324 | #
|
338 |
| -# Another notable mention in this example is setting |
339 |
| -# :gmt-term:`FORMAT_CLOCK_MAP` to **-hhAM** which specifies the format used |
340 |
| -# for time. In this case, leading zeros are removed using (**-**), and only |
341 |
| -# hours are displayed. Additionally, an AM/PM system is used instead of a |
342 |
| -# 24-hour system. More information on configuring time formats can be found |
343 |
| -# at :gmt-term:`FORMAT_CLOCK_MAP`, :gmt-term:`FORMAT_CLOCK_IN`, and |
| 325 | +# Another notable mention in this example is setting :gmt-term:`FORMAT_CLOCK_MAP` to |
| 326 | +# **-hhAM** which specifies the format used for time. In this case, leading zeros are |
| 327 | +# removed using (**-**), and only hours are displayed. Additionally, an AM/PM system is |
| 328 | +# used instead of a 24-hour system. More information on configuring time formats can be |
| 329 | +# found at :gmt-term:`FORMAT_CLOCK_MAP`, :gmt-term:`FORMAT_CLOCK_IN`, and |
344 | 330 | # :gmt-term:`FORMAT_CLOCK_OUT`.
|
345 | 331 |
|
346 | 332 | x = pd.date_range("2021-04-15", periods=8, freq="6H")
|
|
0 commit comments