Skip to content

Major and minor ticks #903

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
sglyon opened this issue Sep 5, 2016 · 9 comments · Fixed by #6166
Closed

Major and minor ticks #903

sglyon opened this issue Sep 5, 2016 · 9 comments · Fixed by #6166
Labels
feature something new

Comments

@sglyon
Copy link

sglyon commented Sep 5, 2016

It would be great if we could distinguish between major and minor ticks a la matplotlib and ggplot2

@etpinard etpinard added the feature something new label Sep 6, 2016
@jensb
Copy link

jensb commented Jan 26, 2017

Yes, I would definitely subscribe to this feature, especially for logarithmically scaled axes. Maybe one of the devels can share some details about what would need to be done (where to start, which function to extend, ...) and maybe then there's a volunteer?

@alexgoldstone
Copy link

Not sure if this warrants its own ticket as it would require background ticks but since it also covers major / minor ticks I thought I'd simply extend this ticket for consideration. I'd like to be able to create something inline with these two example images:
chart
chart2

@kokare-darshan
Copy link

Can we plot two graphs (one with more major ticks, other with less major ticks) and overlay with one graph 50% transparency?

@alexcjohnson
Copy link
Collaborator

Actually, now that we have matching axes I guess you could overlay two or more axes with different tick & grid properties - no transparency needed, but you probably have to put something on the extra axes to get them to show up. An empty invisible trace should suffice.

@slishak
Copy link

slishak commented Jun 29, 2019

Carpet plots already support minor grids, so there is an easy way (although not perfect) to add a minor grid. Python example (may need adapting for different use cases like subplots etc):

from itertools import product


def add_minor_grid(fig, x_range, y_range, major_step_x=1, major_step_y=1, minorgridcount_x=9, minorgridcount_y=9):

    x_list = range(x_range[0], x_range[1]+major_step_x, major_step_x)
    y_list = range(y_range[0], y_range[1]+major_step_y, major_step_y)
    x, y = list(zip(*product(x_list, y_list)))

    fig.add_carpet(
        a=x,
        b=y,
        x=x,
        y=y,
        aaxis={
            'minorgridcount': minorgridcount_x,
            'showticklabels': 'none',
        },
        baxis={
            'minorgridcount': minorgridcount_y,
            'showticklabels': 'none',
        }
    )

    fig.layout.xaxis.range = x_range
    fig.layout.yaxis.range = y_range


from plotly import graph_objs as go
from plotly.offline import plot
fig = go.Figure(
    data=[
        go.Scatter(
            x=[2, 8, 7],
            y=[8, 0, 2]
        )
    ]
)
add_minor_grid(fig, x_range=[0, 10], y_range=[0, 10])
plot(fig)

image

@bmarcote
Copy link

bmarcote commented Jun 5, 2020

I agree: there should be an option to add minor ticks to one axis.
Currently there is only a kind of hack to do it by adding artificially a new axis (see e.g. Major and minor tick marks with Plotly in Stack Overflow), but it has the main limitation that you need to define the values of your axis (it is not possible to leave them automatic).

Given that a minor grid is possible, it should relatively straightforward to use the same axis values considered for the minor grid for generating the minor ticks (shorter than the major ones, and without labels).

@raulf2012
Copy link

raulf2012 commented Jun 5, 2020

@bmarcote On the topic of doing this in a more automated fashion I had cobbled together a python method (for python plotly api) that would help exactly with adding a minor tick axis, see below. It's not beautifal, but it work fine in most cases, even for subplots. Any thoughts on improving would be welcome.

My python method
"""My plot settings and methods.

Author: Raul A. Flores
"""

# Import Modules
import os

import copy

# Plotly imports
import plotly

import chart_studio.plotly as py
import plotly.graph_objs as go

from plotly import io as pyio

def add_duplicate_axes(
    fig,
    axis_type="x",  # 'x' or 'y'
    axis_data=dict(),
    axis_num_list=None,
    tmp_define_both_axis_types=False,
    ):
    """
    Note: range must be set for this to work

    Example usage:

    from plotting.my_plotly import add_duplicate_axes

    shared_axis_data = {
	"tickcolor": "black",
	"ticklen": 3,
	}

    shared_xaxis_data = {
	"dtick": 50,
	**shared_axis_data,
	}

    shared_yaxis_data = {
	"dtick": 1,
	**shared_axis_data,
	}

    shared_meth_props = dict(
	tmp_define_both_axis_types=True,
	)

    add_duplicate_axes(
	fig, axis_type='x',
	axis_data=shared_xaxis_data,
	axis_num_list=[1, ],
	**shared_meth_props)
    add_duplicate_axes(
	fig, axis_type='y',
	axis_data=shared_yaxis_data,
	axis_num_list=[1, ],
	**shared_meth_props)


    """
    # | - add_duplicate_axes

    if axis_type == "x":
        axis_type_other = "y"
    elif axis_type == "y":
        axis_type_other = "x"


    # This is necessary to make sure that the original traces are still visible after adding the new traces
    fig.update_layout(
        # paper_bgcolor="white",
        plot_bgcolor="rgba(255,255,255,0.)",
        )

    axis_info_dict = get_xy_axis_info(fig)[axis_type]
    num_of_axis = axis_info_dict["num_of_axis"]

    # #########################################################################
    if axis_num_list is None:
        axis_num_list = axis_info_dict["axis_num_list"]

    # axis_num_list_new = [i + len(axis_num_list) for i in axis_num_list]
    axis_num_list_new = [i + num_of_axis + 1 for i, j in enumerate(axis_num_list)]

    iterator = enumerate(zip(axis_num_list, axis_num_list_new))
    for i_cnt, (old_index, new_index) in iterator:
        old_Axis = fig.layout[axis_type + "axis" + str(old_index)]

        if old_Axis.range == None:
            print("This doesn't work well if you don't set the range attribute! Do that!")

        new_axis = copy.deepcopy(old_Axis)
        new_axis = new_axis.update(
            showticklabels=False,
            title=dict(
                font=None,
                standoff=None,
                text="",
                ))

        new_axis = new_axis.update(**axis_data)

        axis_key = axis_type + "axis" + str(new_index)
        new_layout = go.Layout({
            axis_key: new_axis,
            })

        fig.update_layout(new_layout)

        if tmp_define_both_axis_types:
            fig.add_scatter(
                **go.Scatter({
                    axis_type + "axis": axis_type + str(new_index),

                    # I added this to fix some issues
                    # It breaks in some applications, look over more closely
                    axis_type_other + "axis": axis_type_other + str(new_index),
                    }).to_plotly_json())

        else:
            fig.add_scatter(
                **go.Scatter({
                    axis_type + "axis": axis_type + str(new_index),
                    }).to_plotly_json())

    # __|
Minimal working example
# Simple Plotly Plot
import plotly.graph_objs as go

x_array = [0, 1, 2, 10]
y_array = [0, 1, 2, 10]

trace = go.Scatter(
    x=x_array,
    y=y_array,
    )
data = [trace]

shared_axis_data = dict(ticks="outside", linecolor="black", showgrid=False, zeroline=False,
    ticklen=12,
    # tickwdith=3,
    tickwidth=3,
    )
layout = go.Layout(
    xaxis=go.layout.XAxis(range=[0, 12], **shared_axis_data),
    yaxis=go.layout.YAxis(range=[0, 12], **shared_axis_data),
    )

fig = go.Figure(data=data, layout=layout)
# fig.show()

from plotting.my_plotly import add_duplicate_axes

shared_axis_data = {
    "tickcolor": "red",
    "ticklen": 6,
    "tickwidth": 2,
    }

shared_xaxis_data = {
    "dtick": 1.,
    **shared_axis_data,
    }

shared_yaxis_data = {
    "dtick": 1.,
    **shared_axis_data,
    }

shared_meth_props = dict(
    tmp_define_both_axis_types=True,
    )

add_duplicate_axes(
    fig, axis_type='x',
    axis_data=shared_xaxis_data,
    axis_num_list=[1, ],
    **shared_meth_props)
add_duplicate_axes(
    fig, axis_type='y',
    axis_data=shared_yaxis_data,
    axis_num_list=[1, ],
    **shared_meth_props)

fig.show()

@avsdev-cw
Copy link

I notice this was marked as having been sponsored back in Feb, is there any update?

@nicolaskruchten
Copy link
Contributor

No updates yet. We do have a sponsor interested in this work but it's not their priority at the moment :)

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

Successfully merging a pull request may close this issue.