Skip to content

Date auto-formatting on xaxis #99

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
prog8 opened this issue Dec 10, 2015 · 16 comments
Closed

Date auto-formatting on xaxis #99

prog8 opened this issue Dec 10, 2015 · 16 comments
Labels
feature something new
Milestone

Comments

@prog8
Copy link

prog8 commented Dec 10, 2015

Hi,
I tried to open a topic on http://community.plot.ly/c/plotly-js but always get a message "Something has gone wrong. Perhaps this topic was closed or deleted while you were looking at it?" so I'm writing here

Is it possible to keep auto-formatting of date depending on range but adjust it a little? Let me explain my case.
Plotly formats date automatically. When year is not needed it skips the year in format but not always. Look at the screenshot above. You can see that first tick always contains a date. Moreover in this case "Dec 9" doesn't have to be shown in all ticks. It can be skipped but it is not. Hour is also displayed in a strange way. I would rather expect something like "7 AM" or "7:00" instead of "07h". I know that I can use tickformat but this totally destroys automatic formatting. It also looks like tickformat cannot be any function which would implement auto-formatting. Any ideas?

selection_246

@etpinard
Copy link
Contributor

@prog8 It is possible to customize the tick format for date using the tickformat axis attribute.

See this example json and associated png.

tickformat uses d3 formatting under the hood. More info here

Hope this helps.

@prog8
Copy link
Author

prog8 commented Dec 15, 2015

Thank you for your answer. I think we misunderstood each other. I know that it is possible to use customer formatting of x axis but as I wrote in previous message when I decide to use custom formatting I lose ability to use auto-formatting when I zoom in and out. Let's imagine that I open a chart for whole year. It makes sense of course to show "%b %y" only but when I keep zooming in it would makes sense to show days, hours, minutes and even seconds. Am I missing something?

@etpinard
Copy link
Contributor

@prog8 My mistake. I didn't catch your mention of tickformat.

Is it possible to keep auto-formatting of date depending on range but adjust it a little?

That sounds like a pretty hard behavior to generalize in a declarative matter. What does a little mean? How would that work?

A potential solution would use a custom on-zoom handler (which doesn't exist yet, similar to plotly_hover) assessing the new range after a zoom and call Plotly.relayout('graph', 'xaxis.tickformat', /* new format string */) accordingly.

@prog8
Copy link
Author

prog8 commented Dec 15, 2015

I know that this can be hard to generalize but I was wondering why default behavior produces things like full date in the first tick and hour format like "09h" which is not what an average user could expect.

@etpinard
Copy link
Contributor

@prog8 can you paste a reproducible example of this behavior? Debugging from a screenshot is hard.

@prog8
Copy link
Author

prog8 commented Dec 15, 2015

@etpinard sure. Here is an example: data series, layout, config

[{"type":"scatter","name":"Test","x":["2015-11-23 09:27:00","2015-11-23 09:28:00","2015-11-23 09:29:00","2015-11-23 09:30:00","2015-11-23 09:31:00","2015-11-23 09:32:00","2015-11-23 09:33:00","2015-11-23 09:34:00","2015-11-23 09:35:00","2015-11-23 09:36:00","2015-11-23 09:37:00","2015-11-23 09:38:00","2015-11-23 09:39:00","2015-11-23 09:40:00","2015-11-23 09:41:00","2015-11-23 09:42:00","2015-11-23 09:43:00","2015-11-23 09:44:00","2015-11-23 09:45:00","2015-11-23 09:46:00","2015-11-23 09:47:00","2015-11-23 09:48:00","2015-11-23 09:49:00","2015-11-23 09:50:00","2015-11-23 09:51:00","2015-11-23 09:52:00","2015-11-23 09:53:00","2015-11-23 09:54:00","2015-11-23 09:55:00","2015-11-23 09:56:00","2015-11-23 09:57:00","2015-11-23 09:58:00","2015-11-23 09:59:00","2015-11-23 10:00:00","2015-11-23 10:01:00","2015-11-23 10:02:00","2015-11-23 10:03:00","2015-11-23 10:04:00","2015-11-23 10:05:00","2015-11-23 10:06:00","2015-11-23 10:07:00","2015-11-23 10:08:00","2015-11-23 10:09:00","2015-11-23 10:10:00","2015-11-23 10:11:00","2015-11-23 10:12:00","2015-11-23 10:13:00","2015-11-23 10:14:00","2015-11-23 10:15:00","2015-11-23 10:16:00","2015-11-23 10:17:00","2015-11-23 10:18:00","2015-11-23 10:19:00","2015-11-23 10:20:00","2015-11-23 10:21:00","2015-11-23 10:22:00","2015-11-23 10:23:00","2015-11-23 10:24:00","2015-11-23 10:25:00","2015-11-23 10:26:00","2015-11-23 10:27:00","2015-11-23 10:28:00","2015-11-23 10:29:00","2015-11-23 10:30:00","2015-11-23 10:31:00","2015-11-23 10:32:00","2015-11-23 10:33:00","2015-11-23 10:34:00","2015-11-23 10:35:00","2015-11-23 10:36:00","2015-11-23 10:37:00","2015-11-23 10:38:00","2015-11-23 10:39:00","2015-11-23 10:40:00","2015-11-23 10:41:00","2015-11-23 10:42:00","2015-11-23 10:43:00","2015-11-23 10:44:00","2015-11-23 10:45:00","2015-11-23 10:46:00","2015-11-23 10:47:00","2015-11-23 10:48:00","2015-11-23 10:49:00","2015-11-23 10:50:00","2015-11-23 10:51:00","2015-11-23 10:52:00","2015-11-23 10:53:00","2015-11-23 10:54:00","2015-11-23 10:55:00","2015-11-23 10:56:00","2015-11-23 10:57:00","2015-11-23 10:58:00","2015-11-23 10:59:00","2015-11-23 11:00:00","2015-11-23 11:01:00","2015-11-23 11:02:00","2015-11-23 11:03:00","2015-11-23 11:04:00","2015-11-23 11:05:00","2015-11-23 11:06:00","2015-11-23 11:07:00","2015-11-23 11:08:00","2015-11-23 11:09:00","2015-11-23 11:10:00","2015-11-23 11:11:00","2015-11-23 11:12:00","2015-11-23 11:13:00","2015-11-23 11:14:00","2015-11-23 11:15:00","2015-11-23 11:16:00","2015-11-23 11:17:00","2015-11-23 11:18:00","2015-11-23 11:19:00"],"y":[0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,123,3,0,0,0,0,0,15,16,17,17,111,120,123,126,432,320,0,23,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"line":{"shape":"spline"},"marker":{"color":"#69D2E7","colors":"#69D2E7"},"mode":"lines+markers","fill":null}]

{"autosize":true,"width":655.5,"height":180,"showlegend":true,"yaxis":{"fixedrange":true},"margin":{"l":40,"r":20,"b":30,"t":10,"pad":4}}

{"showLink":false,"sendData":false,"displaylogo":false,"modeBarButtonsToRemove":["sendDataToCloud","pan2d","hoverClosestCartesian","hoverCompareCartesian","zoom2d"]}

@etpinard
Copy link
Contributor

@prog8 Interesting. With your specs, Plotly.plot gives me:

image

no 07h.

@etpinard
Copy link
Contributor

Maybe another library is conflicting with plotly.js on your page.

@prog8
Copy link
Author

prog8 commented Dec 15, 2015

Even when you zoom out?

@etpinard
Copy link
Contributor

@prog8 Ah. Now I see it. Investigating ....

@alexcjohnson
Copy link
Collaborator

This is the expected behavior but we can debate whether that's really ideal. We need to have the date in this case, because you commonly span into a second day, and I thought Dec 9 07:00 was getting a bit long - but you're right that that would be a more standard time format.

@neonrust
Copy link

A bit late, but I was wondering this as well.
I do (also) think that "08:00" is better than "08h" (and only slightly more than 1 character wider, using variable font).
I also vote for the date to be dropped when it's the same as previous tick.

@cjgordon
Copy link

My thoughts are similar to most charting libraries the tick format to be configurable as a function, pseudo code would be something like:

tickformat : function (val) {
           /* some logic based on the current axis tick value here */
           if ('this value is midnight') {
                return '18/05';
           } else {
               return '11:00';
           }
}

I'm pretty desperate to have better controller over the formatting of the time series x-axis as it currently just doesn't look right/good so I will attempt to add this functionality. Will let you know how I go.

@agarwalhitesh83
Copy link

tick format should be configurable as a function for y-axis as well. Currently could not find an example where we show alphanumeric text in y-axis (E.g. Traffic in bytes)

@cjgordon
Copy link

cjgordon commented Sep 2, 2016

Okay. I dived deep into this one and came up with the following result:
http://pasteboard.co/gGXdmWbdi.gif

Basically I wanted the auto formatted x-axis ticks to show the first tick as the hour, day and month and every tick that is midnight to also display the hour, day and month. I think this looks much better than the default hour tick which was %b %-d %Hh and had the year on a new line. I investigated making tickformat a function, and also using the tickmode 'array' and manually calculating the ticks to pass into Plotly plot function however these options were quite complex/looked very time consuming to complete.

What I ended up doing was manually modifying the formatDate function of Ploty to the following:

function formatDate(ax, out, hover, extraPrecision) {
var x = out.x,
    tr = ax._tickround,
    d = new Date(x),
    // suffix completes the full date info, to be included
    // with only the first tick
    suffix = '',
    tt;
if(hover && ax.hoverformat) {
    tt = modDateFormat(ax.hoverformat,x);
}
else if(ax.tickformat) {
    tt = modDateFormat(ax.tickformat,x);
    // TODO: potentially hunt for ways to automatically add more
    // precision to the hover text?
}
else {
    if(extraPrecision) {
        if(isNumeric(tr)) tr+=2;
        else tr = {y: 'm', m: 'd', d: 'H', H: 'M', M: 'S', S: 2}[tr];
    }

    if(tr==='y') tt = yearFormat(d);
    else if(tr==='m') tt = monthFormat(d);
    else {
        if(x===ax._tmin && !hover) {
            suffix = '<br>'+dayFormat(d);
        }

        if(tr==='d') tt = dayFormat(d);
        else if(tr==='H') {
            tt = hourSpecial(d);
            if (tt=='00:00') {
                tt =  hourSpecial(d)+'<br>'+dayFormat(d);
            }
        } else {
            if(x===ax._tmin && !hover) {
                suffix = '<br>'+dayFormat(d);//+', '+yearFormat(d);
            }

            tt = minuteFormat(d);
            if(tr!=='M') {
                tt += secondFormat(d);
                if(tr!=='S') {
                    tt += numFormat(mod(x/1000,1),ax,'none',hover)
                        .substr(1);
                }
            }
        } 
    }
}
out.text = tt + suffix;

}

It's a bit of a hacky solution but it provided me with the best time to result. I'm not sure what the better long term solution for Plotly would be but I think opening up the auto tick date formats as layout configuration options, maybe have options for the format of first tick, hour tick marks, and midnight tick marks?

Hope that helps someone.

EDIT: Fixed image link.

@etpinard etpinard added this to the Better dates milestone Sep 7, 2016
@etpinard etpinard added the feature something new label Sep 7, 2016
@alexcjohnson
Copy link
Collaborator

the "09h" type format has been removed from the auto-formatting routine as part of #1078 - this also changes some other subtle bits of the formatting, like in cases where the date got pushed to a second line, now it shows up on every tick where the date changes, rather than just the first tick. This doesn't give the full flexibility folks had discussed above, but it does address the most common reason you WANTED that flexibility. Going to close this for now, but feel free to reopen or open a new issue with a specific use case that would benefit from more flexibility. Thanks for the discussion!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature something new
Projects
None yet
Development

No branches or pull requests

6 participants