Skip to content
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

Feature Proposal: New tick mode: proportional #6824

Open
ayjayt opened this issue Dec 25, 2023 · 5 comments
Open

Feature Proposal: New tick mode: proportional #6824

ayjayt opened this issue Dec 25, 2023 · 5 comments
Assignees

Comments

@ayjayt
Copy link
Contributor

ayjayt commented Dec 25, 2023

What

Add a new tick mode:

# Usage:
xaxis: {
    tickmode: 'proportional',
    tickvals: [0, .5, 1],
}

Effect:

Plotly will make ticks propotional to the range: So if the x range is [50, 150], the tick marks will appear at 50, 100, and 150. If the xrange is [-0.5, 1.5], the tick marks will appear at -0.5, 0.5, and 1.5.

Why

Auto tick formatting is usually ugly (for any value ntick), and the other modes aren't responsive to user zooms.

Workaround: Using python w/ jlab, but I can calculate ticks manually on range changes and during rendering, and then use array mode, but it is clunky, and requires my users to have the plotly installed in their kernel and on jlab server. My proposal doesn't seem that different than modifying auto behavior, so I'll take a shot.

Who am I

Working on analysis software for geologists who design wells.

@alexcjohnson
Copy link
Collaborator

@ayjayt thanks for the issue and related PR.

Just to make sure I understand your goals here: Our automatic ticks try to give nice round numbers, but the cost of doing that, in general, is that you won't have ticks exactly at the ends of the axis range. What you're proposing here, putting ticks at precise fractions of the axis length, does show the axis range exactly (at least if you include 0 and 1 in the list) at the expense of round values. I'll note that we have the same tradeoff with tickmode='sync', where the tick positions are set by the other axis and therefore their values are in general not nice round numbers.

Another way to accomplish a subset of the functionality you're proposing but with a more concise API would be to continue using nticks but make a tickmode that forces ticks at both ends and then divides up the axis evenly, ie the tick spacing is exactly (range[1] - range[0]) / (nticks - 1), so your example would have nticks=3. If you instead wanted ticks at the ends and every quarter of the axis you would set nticks=5.

That feels to me like it would cover most of the uses for this feature, do you ever foresee wanting to use this with tickvals that are either (a) not evenly spaced or (b) not spanning exactly 0 to 1? We could of course start with one of these and then add the other later, but if nearly everyone will use the simpler one we should start there.

Re: naming - to me the key here is that (in the variant I'm proposing) the ticks span the whole domain, so maybe we just say that: tickmode='full domain'? And in the original variant you provide an array of fractions of the axis domain, so perhaps this mode could be called tickmode='domain array'?

@ayjayt
Copy link
Contributor Author

ayjayt commented Jan 2, 2024

Yeah, that's it.

Some contexts:

  1. These scientists don't work w/ round numbers- units are radiation and density and molarity and such, no constants are round. They (read: I, as I am making their API) will use formatting to be aware of precision/error.
  2. Trying to achieve feature parity w/ a competitor, which motivates this request.

Re: naming - to me the key here is that (in the variant I'm proposing) the ticks span the whole domain, so maybe we just say that: tickmode='full domain'? And in the original variant you provide an array of fractions of the axis domain, so perhaps this mode could be called tickmode='domain array'?

I'm totally fine w/ changing the name. The nice thing about the domain array strategy is that it's a very simple pre-calc step before your existing code does the tickmode='array' calc. The code calculates what the equivalent tickmode='array' values would be, and then pretends to be tickmode='array'. I would be happy to implement the full domain strategy if I could just do the same thing- generate a domain array based on full domain values, and then generate a regular array based on that.

@alexcjohnson
Copy link
Collaborator

OK great. I suspect if the goal is feature parity, these ticks will always be evenly spaced, ie what I'm proposing as tickmode='full domain'. So let's start with just that and if a need arises later we can add tickmode='domain array'.

In that case the implementation can be even simpler than you're suggesting: generate tick0 = range[0] and dtick = Math.abs((range[1] - range[0]) / (nticks - 1)) and then let the auto/linear algorithm take it from there.

Please note a few extra situations we'll want to pay attention to:

  • Category axes should not accept tickmode='domain array' at all, since they aren't continuous so this would have no meaning.
  • Log axes I guess should be OK, but we'll need to be check that the tick values they display are meaningful.
  • Other subplot types reuse a lot of this logic, so it either needs to be tested in all of these or explicitly excluded: 3D, polar, ternary, maybe parcoords, probably some others I'm not thinking of right now...
  • We should also ensure dynamic behavior is clean, ie when labels update while you're dragging the axis or an end of the axis.

@ayjayt
Copy link
Contributor Author

ayjayt commented Jan 3, 2024

Sounds good, will try and get it done post haste.

@ayjayt
Copy link
Contributor Author

ayjayt commented Jan 12, 2024

a pull request with the feature, but with my original proportional implementation, is ready if that's acceptable.

Otherwise next week after I have some response on parameterization and on ticktext I'll use the auto algo as suggested above.

The majority of work here was in testing (it allowed me to find the duplicate-tick bug we patched) and downgrading my ES6 to ES5, actual implementation easy-peazy .

Video demo of current implementation of domain array (was called proportional).

@gvwilson gvwilson self-assigned this Jul 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants