You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Report date and time of cursor position on a plot_date plot #7582
When plotting with DateTime on the x axis, it would be useful to show both the date and time in the cursor position. Currently only the date or time is shown, depending on zoom level.
Example: only the date is shown in bottom left (x=2016-10-16)
Current master installed using pip, Linux, python 3.5.2
The value shown the bar is by default pulled from the axis Formaterr via the format_data_short method. The default implementation is just the delegate to fomat_data which in turn delegates to __call__ (for historical reasons).
To trace through the call path here, in backend_bases.NavigationToolbar2.mouse_move (which is hooked up to the mouse move callback) calls Axes.format_coord and puts the result in the GUI msg area. format_coord (in axes/_base.py) calls format_xdata / format_ydata which in turn check if there is a user supplied fmt_xdata or fmt_ydata attributes on the Axes object and if not calls the axis's major formatters format_data_short method.
The specific work here is:
add a format_data_short method to the auto data formatter that uses the next more precise format from what __call__ uses.
I don't think there's a way to make this work for everyone, in the sense that most of the time I'd think you'd only want to use the date OR the time? Probably a doc recipe (which could be, in an ideal world, as simple as ax.xaxis.get_major_formatter().format_data_short = lambda pos: lambda pos: mdates.num2date(pos).strftime("%Y-%m-%d; %H:%M:%S") would be better?
Anyways, while trying to come up with such a recipe, I found a bunch of issues with datetime and ticker handling.
matplotlib.dates should probably export its own strftime function which transparently handles matplotlib timestamps (avoiding the need to call num2date explicitly).
The fact that formatters are callable, which I argued against in New Formatter API #5804, makes it possible to write ax.format_xdata = Formatter(...) (e.g. examples/api/date_demo.py), which is a mess as the axes' formatter instance is not correctly set, so format_data_short confusingly doesn't work -- that example really needs to be changed to something like
or alternatively we should just make Axes.format_xdata a property that redirects to Axes.xaxis.major.formatter, so that one can assign to format_xdata and then to format_xdata.format_data_short. (Actually the second solution isn't bad...)
In other words the pile of redirections going on is really hard to keep track of. (Unlabeling as "easy" and "new-contributor-friendly" for this reason.)
examples/api/date_index_formatter.py makes no sense, especially its docstring? Neither plot is labelling or plotting week-ends.
The two use cases I currently frequently encounter are:
Looking at a large scale overview (as above), but wanting to know the time of an obvious feature
Zooming into data (e.g. the data above) to look at precisely where a feature is, but then loosing information about the date. This means having to zoom back out again to try and find the feature in 'date zoomlevel'.
Even if you want to know one or the other, showing both doesn't (as far as I can see) impact on this.
My point was that showing too much info could be slightly annoying when the timescale is obviously either very large or very small, but I guess that's not a big cost (and erring on the side of too much info is probably better). In that case I'd suggest always showing cursor data either with the %c (locale) strftime format, or with isoformat().
Perhaps this feature needs a complete overhaul? Perhaps supporting a format
string with named components? That way, the user can easily customize the
output. The hard part will be trying to automatically generate a good
default format string.
Activity
tacaswell commentedon Dec 7, 2016
The value shown the bar is by default pulled from the axis
Formaterrvia theformat_data_shortmethod. The default implementation is just the delegate tofomat_datawhich in turn delegates to__call__(for historical reasons).To trace through the call path here, in
backend_bases.NavigationToolbar2.mouse_move(which is hooked up to the mouse move callback) callsAxes.format_coordand puts the result in the GUI msg area.format_coord(inaxes/_base.py) callsformat_xdata/format_ydatawhich in turn check if there is a user suppliedfmt_xdataorfmt_ydataattributes on theAxesobject and if not calls the axis's major formattersformat_data_shortmethod.The specific work here is:
format_data_shortmethod to the auto data formatter that uses the next more precise format from what__call__uses.attn @anntzer
anntzer commentedon Dec 7, 2016
I don't think there's a way to make this work for everyone, in the sense that most of the time I'd think you'd only want to use the date OR the time? Probably a doc recipe (which could be, in an ideal world, as simple as
ax.xaxis.get_major_formatter().format_data_short = lambda pos: lambda pos: mdates.num2date(pos).strftime("%Y-%m-%d; %H:%M:%S")would be better?Anyways, while trying to come up with such a recipe, I found a bunch of issues with datetime and ticker handling.
matplotlib.datesshould probably export its ownstrftimefunction which transparently handles matplotlib timestamps (avoiding the need to callnum2dateexplicitly).The fact that formatters are callable, which I argued against in New Formatter API #5804, makes it possible to write
ax.format_xdata = Formatter(...)(e.g.examples/api/date_demo.py), which is a mess as the axes' formatter instance is not correctly set, soformat_data_shortconfusingly doesn't work -- that example really needs to be changed to something likeor alternatively we should just make
Axes.format_xdataa property that redirects toAxes.xaxis.major.formatter, so that one can assign toformat_xdataand then toformat_xdata.format_data_short. (Actually the second solution isn't bad...)In other words the pile of redirections going on is really hard to keep track of. (Unlabeling as "easy" and "new-contributor-friendly" for this reason.)
examples/api/date_index_formatter.pymakes no sense, especially its docstring? Neither plot is labelling or plotting week-ends.dstansby commentedon Dec 7, 2016
The two use cases I currently frequently encounter are:
Even if you want to know one or the other, showing both doesn't (as far as I can see) impact on this.
anntzer commentedon Dec 7, 2016
My point was that showing too much info could be slightly annoying when the timescale is obviously either very large or very small, but I guess that's not a big cost (and erring on the side of too much info is probably better). In that case I'd suggest always showing cursor data either with the %c (locale) strftime format, or with isoformat().
jklymak commentedon Mar 24, 2018
#10084 does the annoying thing of the big label. Its actually not that annoying.
WeatherGod commentedon Mar 24, 2018
jklymak commentedon Mar 24, 2018
there is a method to change that display, but I forget what its called.
jklymak commentedon Mar 24, 2018
Ax.format_cursor
dstansby commentedon Apr 8, 2018
I think this has improved enough for me to close the original issue now.