| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent d4b42b6 commit 9b7966b
6 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -240,6 +240,7 @@ per-file-ignores = | |||
| 240 | 240 | examples/text_labels_and_annotations/tex_demo.py: E402 | |
| 241 | 241 | examples/text_labels_and_annotations/watermark_text.py: E402 | |
| 242 | 242 | examples/ticks_and_spines/auto_ticks.py: E501 | |
| 243 | + examples/ticks_and_spines/date_concise_formatter.py: E402 | ||
| 243 | 244 | examples/user_interfaces/canvasagg.py: E402 | |
| 244 | 245 | examples/user_interfaces/embedding_in_gtk3_panzoom_sgskip.py: E402 | |
| 245 | 246 | examples/user_interfaces/embedding_in_gtk3_sgskip.py: E402 | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,40 @@ | |||
| 1 | + :orphan: | ||
| 2 | + | ||
| 3 | + New date formatter: `~.dates.ConciseDateFormatter` | ||
| 4 | + -------------------------------------------------- | ||
| 5 | + | ||
| 6 | + The automatic date formatter used by default can be quite verbose. A new | ||
| 7 | + formatter can be accessed that tries to make the tick labels appropriately | ||
| 8 | + concise. | ||
| 9 | + | ||
| 10 | + .. plot:: | ||
| 11 | + | ||
| 12 | + import datetime | ||
| 13 | + import matplotlib.pyplot as plt | ||
| 14 | + import matplotlib.dates as mdates | ||
| 15 | + import numpy as np | ||
| 16 | + | ||
| 17 | + # make a timeseries... | ||
| 18 | + base = datetime.datetime(2005, 2, 1) | ||
| 19 | + dates = np.array([base + datetime.timedelta(hours= 2 * i) | ||
| 20 | + for i in range(732)]) | ||
| 21 | + N = len(dates) | ||
| 22 | + np.random.seed(19680801) | ||
| 23 | + y = np.cumsum(np.random.randn(N)) | ||
| 24 | + | ||
| 25 | + lims = [(np.datetime64('2005-02'), np.datetime64('2005-04')), | ||
| 26 | + (np.datetime64('2005-02-03'), np.datetime64('2005-02-15')), | ||
| 27 | + (np.datetime64('2005-02-03 11:00'), np.datetime64('2005-02-04 13:20'))] | ||
| 28 | + fig, axs = plt.subplots(3, 1, constrained_layout=True) | ||
| 29 | + for nn, ax in enumerate(axs): | ||
| 30 | + # activate the formatter here. | ||
| 31 | + locator = mdates.AutoDateLocator() | ||
| 32 | + formatter = mdates.ConciseDateFormatter(locator) | ||
| 33 | + ax.xaxis.set_major_locator(locator) | ||
| 34 | + ax.xaxis.set_major_formatter(formatter) | ||
| 35 | + | ||
| 36 | + ax.plot(dates, y) | ||
| 37 | + ax.set_xlim(lims[nn]) | ||
| 38 | + axs[0].set_title('Concise Date Formatter') | ||
| 39 | + | ||
| 40 | + plt.show() | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,183 @@ | |||
| 1 | + """ | ||
| 2 | + ================================================ | ||
| 3 | + Formatting date ticks using ConciseDateFormatter | ||
| 4 | + ================================================ | ||
| 5 | + | ||
| 6 | + Finding good tick values and formatting the ticks for an axis that | ||
| 7 | + has date data is often a challenge. `~.dates.ConciseDateFormatter` is | ||
| 8 | + meant to improve the strings chosen for the ticklabels, and to minimize | ||
| 9 | + the strings used in those tick labels as much as possible. | ||
| 10 | + | ||
| 11 | + .. note:: | ||
| 12 | + | ||
| 13 | + This formatter is a candidate to become the default date tick formatter | ||
| 14 | + in future versions of Matplotlib. Please report any issues or | ||
| 15 | + suggestions for improvement to the github repository or mailing list. | ||
| 16 | + | ||
| 17 | + """ | ||
| 18 | + import datetime | ||
| 19 | + import matplotlib.pyplot as plt | ||
| 20 | + import matplotlib.dates as mdates | ||
| 21 | + import numpy as np | ||
| 22 | + | ||
| 23 | + ############################################################################# | ||
| 24 | + # First, the default formatter. | ||
| 25 | + | ||
| 26 | + base = datetime.datetime(2005, 2, 1) | ||
| 27 | + dates = np.array([base + datetime.timedelta(hours=(2 * i)) | ||
| 28 | + for i in range(732)]) | ||
| 29 | + N = len(dates) | ||
| 30 | + np.random.seed(19680801) | ||
| 31 | + y = np.cumsum(np.random.randn(N)) | ||
| 32 | + | ||
| 33 | + fig, axs = plt.subplots(3, 1, constrained_layout=True, figsize=(6, 6)) | ||
| 34 | + lims = [(np.datetime64('2005-02'), np.datetime64('2005-04')), | ||
| 35 | + (np.datetime64('2005-02-03'), np.datetime64('2005-02-15')), | ||
| 36 | + (np.datetime64('2005-02-03 11:00'), np.datetime64('2005-02-04 13:20'))] | ||
| 37 | + for nn, ax in enumerate(axs): | ||
| 38 | + ax.plot(dates, y) | ||
| 39 | + ax.set_xlim(lims[nn]) | ||
| 40 | + # rotate_labels... | ||
| 41 | + for label in ax.get_xticklabels(): | ||
| 42 | + label.set_rotation(40) | ||
| 43 | + label.set_horizontalalignment('right') | ||
| 44 | + axs[0].set_title('Default Date Formatter') | ||
| 45 | + plt.show() | ||
| 46 | + | ||
| 47 | + ############################################################################# | ||
| 48 | + # The default date formater is quite verbose, so we have the option of | ||
| 49 | + # using `~.dates.ConciseDateFormatter`, as shown below. Note that | ||
| 50 | + # for this example the labels do not need to be rotated as they do for the | ||
| 51 | + # default formatter because the labels are as small as possible. | ||
| 52 | + | ||
| 53 | + fig, axs = plt.subplots(3, 1, constrained_layout=True, figsize=(6, 6)) | ||
| 54 | + for nn, ax in enumerate(axs): | ||
| 55 | + locator = mdates.AutoDateLocator(minticks=3, maxticks=7) | ||
| 56 | + formatter = mdates.ConciseDateFormatter(locator) | ||
| 57 | + ax.xaxis.set_major_locator(locator) | ||
| 58 | + ax.xaxis.set_major_formatter(formatter) | ||
| 59 | + | ||
| 60 | + ax.plot(dates, y) | ||
| 61 | + ax.set_xlim(lims[nn]) | ||
| 62 | + axs[0].set_title('Concise Date Formatter') | ||
| 63 | + | ||
| 64 | + plt.show() | ||
| 65 | + | ||
| 66 | + ############################################################################# | ||
| 67 | + # If all calls to axes that have dates are to be made using this converter, | ||
| 68 | + # it is probably most convenient to use the units registry where you do | ||
| 69 | + # imports: | ||
| 70 | + | ||
| 71 | + import matplotlib.units as munits | ||
| 72 | + converter = mdates.ConciseDateConverter() | ||
| 73 | + munits.registry[np.datetime64] = converter | ||
| 74 | + munits.registry[datetime.date] = converter | ||
| 75 | + munits.registry[datetime.datetime] = converter | ||
| 76 | + | ||
| 77 | + fig, axs = plt.subplots(3, 1, figsize=(6, 6), constrained_layout=True) | ||
| 78 | + for nn, ax in enumerate(axs): | ||
| 79 | + ax.plot(dates, y) | ||
| 80 | + ax.set_xlim(lims[nn]) | ||
| 81 | + axs[0].set_title('Concise Date Formatter') | ||
| 82 | + | ||
| 83 | + plt.show() | ||
| 84 | + | ||
| 85 | + ############################################################################# | ||
| 86 | + # Localization of date formats | ||
| 87 | + # ============================ | ||
| 88 | + # | ||
| 89 | + # Dates formats can be localized if the default formats are not desirable by | ||
| 90 | + # manipulating one of three lists of strings. | ||
| 91 | + # | ||
| 92 | + # The ``formatter.formats`` list of formats is for the normal tick labels, | ||
| 93 | + # There are six levels: years, months, days, hours, minutes, seconds. | ||
| 94 | + # The ``formatter.offset_formats`` is how the "offset" string on the right | ||
| 95 | + # of the axis is formatted. This is usually much more verbose than the tick | ||
| 96 | + # labels. Finally, the ``formatter.zero_formats`` are the formats of the | ||
| 97 | + # ticks that are "zeros". These are tick values that are either the first of | ||
| 98 | + # the year, month, or day of month, or the zeroth hour, minute, or second. | ||
| 99 | + # These are usually the same as the format of | ||
| 100 | + # the ticks a level above. For example if the axis limts mean the ticks are | ||
| 101 | + # mostly days, then we label 1 Mar 2005 simply with a "Mar". If the axis | ||
| 102 | + # limits are mostly hours, we label Feb 4 00:00 as simply "Feb-4". | ||
| 103 | + # | ||
| 104 | + # Note that these format lists can also be passed to `.ConciseDateFormatter` | ||
| 105 | + # as optional kwargs. | ||
| 106 | + # | ||
| 107 | + # Here we modify the labels to be "day month year", instead of the ISO | ||
| 108 | + # "year month day": | ||
| 109 | + | ||
| 110 | + fig, axs = plt.subplots(3, 1, constrained_layout=True, figsize=(6, 6)) | ||
| 111 | + | ||
| 112 | + for nn, ax in enumerate(axs): | ||
| 113 | + locator = mdates.AutoDateLocator() | ||
| 114 | + formatter = mdates.ConciseDateFormatter(locator) | ||
| 115 | + formatter.formats = ['%y', # ticks are mostly years | ||
| 116 | + '%b', # ticks are mostly months | ||
| 117 | + '%d', # ticks are mostly days | ||
| 118 | + '%H:%M', # hrs | ||
| 119 | + '%H:%M', # min | ||
| 120 | + '%S.%f', ] # secs | ||
| 121 | + # these are mostly just the level above... | ||
| 122 | + formatter.zero_formats = [''] + formatter.formats[:-1] | ||
| 123 | + # ...except for ticks that are mostly hours, then it is nice to have | ||
| 124 | + # month-day: | ||
| 125 | + formatter.zero_formats[3] = '%d-%b' | ||
| 126 | + | ||
| 127 | + formatter.offset_formats = ['', | ||
| 128 | + '%Y', | ||
| 129 | + '%b %Y', | ||
| 130 | + '%d %b %Y', | ||
| 131 | + '%d %b %Y', | ||
| 132 | + '%d %b %Y %H:%M', ] | ||
| 133 | + ax.xaxis.set_major_locator(locator) | ||
| 134 | + ax.xaxis.set_major_formatter(formatter) | ||
| 135 | + | ||
| 136 | + ax.plot(dates, y) | ||
| 137 | + ax.set_xlim(lims[nn]) | ||
| 138 | + axs[0].set_title('Concise Date Formatter') | ||
| 139 | + | ||
| 140 | + plt.show() | ||
| 141 | + | ||
| 142 | + ############################################################################# | ||
| 143 | + # Registering a converter with localization | ||
| 144 | + # ========================================= | ||
| 145 | + # | ||
| 146 | + # `.ConciseDateFormatter` doesn't have rcParams entries, but localization | ||
| 147 | + # can be accomplished by passing kwargs to `~.ConciseDateConverter` and | ||
| 148 | + # registering the datatypes you will use with the units registry: | ||
| 149 | + | ||
| 150 | + import datetime | ||
| 151 | + | ||
| 152 | + formats = ['%y', # ticks are mostly years | ||
| 153 | + '%b', # ticks are mostly months | ||
| 154 | + '%d', # ticks are mostly days | ||
| 155 | + '%H:%M', # hrs | ||
| 156 | + '%H:%M', # min | ||
| 157 | + '%S.%f', ] # secs | ||
| 158 | + # these can be the same, except offset by one level.... | ||
| 159 | + zero_formats = [''] + formats[:-1] | ||
| 160 | + # ...except for ticks that are mostly hours, then its nice to have month-day | ||
| 161 | + zero_formats[3] = '%d-%b' | ||
| 162 | + offset_formats = ['', | ||
| 163 | + '%Y', | ||
| 164 | + '%b %Y', | ||
| 165 | + '%d %b %Y', | ||
| 166 | + '%d %b %Y', | ||
| 167 | + '%d %b %Y %H:%M', ] | ||
| 168 | + | ||
| 169 | + converter = mdates.ConciseDateConverter(formats=formats, | ||
| 170 | + zero_formats=zero_formats, | ||
| 171 | + offset_formats=offset_formats) | ||
| 172 | + | ||
| 173 | + munits.registry[np.datetime64] = converter | ||
| 174 | + munits.registry[datetime.date] = converter | ||
| 175 | + munits.registry[datetime.datetime] = converter | ||
| 176 | + | ||
| 177 | + fig, axs = plt.subplots(3, 1, constrained_layout=True, figsize=(6, 6)) | ||
| 178 | + for nn, ax in enumerate(axs): | ||
| 179 | + ax.plot(dates, y) | ||
| 180 | + ax.set_xlim(lims[nn]) | ||
| 181 | + axs[0].set_title('Concise Date Formatter registered non-default') | ||
| 182 | + | ||
| 183 | + plt.show() | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments