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

Line Markers are cut off at edge of plot area #826

Closed
petergaultney opened this issue Sep 10, 2017 · 17 comments
Closed

Line Markers are cut off at edge of plot area #826

petergaultney opened this issue Sep 10, 2017 · 17 comments

Comments

@petergaultney
Copy link

screenshot 2017-09-10 13 17 42

Other plotting frameworks allow those markers to overlap the edge, making things look a lot nicer.

screenshot 2017-09-10 13 19 54

@cldougl
Copy link
Member

cldougl commented Sep 10, 2017

Hi there,
Can you clarify what you mean by overlapping the edge in the second graph?
Typically we would expect the markers to look like this:

screen shot 2017-09-10 at 6 49 57 pm

You can see more examples here: https://plot.ly/python/line-charts/

If you're getting a different result perhaps you could attach the code you're using.

@petergaultney
Copy link
Author

I mean that the entire 'circle' of the marker is visible in all cases in the second example (which was done with a different plotting framework), whereas the Plotly (1st) example shows that the markers at the edge of the plot get 'cut off' by the top, bottom, and sides of the plot, so only half (or, at the corner, 1/4) of the marker is visible.

@cldougl
Copy link
Member

cldougl commented Sep 11, 2017

@petergaultney as previously mentioned, it's not the default result to cut off the markers. It would helpful if you could share a code for a reproducible example

@petergaultney
Copy link
Author

Ah, I didn't understand that you were saying that wasn't expected behavior.

It happens on multiple plots that I am doing. Here is the code for one of them.

data = list()
prev_data = [0.0 for week_name in week_names]
for team in reversed(last_team_order):
    ys = [prev + 100 * cur for prev, cur in zip(prev_data, teams[team])]
    prev_data = ys
    text = [str(100 * prob) + '%' for prob in teams[team]]
    data.append(
        go.Scatter(
            x=week_names,
            y=ys,
            mode='lines+markers',
            line=dict(width=8, color=rgb(div.colors[team][1])),
            fill='tonexty',
            fillcolor=rgb(div.colors[team][0]),
            marker=dict(size=14, color=rgb(div.colors[team][1]),
                        line=dict(width=3, color=rgb(div.colors[team][0]))),
            name=team,
            text=text,
            hoverinfo='x+text'
    ))
layout = go.Layout(
    title='{} {} Weekly Championship Probabilities'.format(confname, div.name),
    showlegend=True,
    xaxis=dict(type='category'),
    yaxis=dict(type='linear', range=[0,100],
               dtick=10,
               ticksuffix='%'
    ),
    paper_bgcolor=rgb(conf_bgs[confname]),
    plot_bgcolor=rgb(conf_bgs[confname]),
    legend=dict(orientation="h"),
)
fig = go.Figure(data=data, layout=layout)
div = plot(fig, include_plotlyjs=False, output_type='div')

And I'll attach the resulting html as well.

example.zip

@cldougl
Copy link
Member

cldougl commented Sep 11, 2017

Thanks for including the example. The issue you're running into is related to using the fill. If you comment out the fill lines:

            fill='tonexty',
            fillcolor=rgb(div.colors[team][0]),

in the example you've attached you'll get an image similar to the second example (the non-plotly chart) that you've attached in your original comment (note this example does not include a fill.)

The expected behavior of the fill is to remove the chart padding when there is a fill to zero trace: https://github.com/plotly/plotly.js/blob/master/src/traces/scatter/calc.js#L89

@petergaultney
Copy link
Author

Thanks for the explanation. I think I understand why this choice was made, but it would be nice if there were a way to hint to the underlying plotter that the padding was still desired.

As a datapoint, Pygal supports allowing the markers to spill over into the padding even on stacked/filled area charts: http://www.pygal.org/en/stable/documentation/types/line.html#stacked

It sounds like it might be possible for me to work around this undesired (for me) behavior by inserting a single extra trace below the first trace that does not include a fill, has line width 0 (is invisible), and is hidden from the legend with showlegend=False? Or am I misunderstanding your comment?

@petergaultney
Copy link
Author

Actually, looking at the code you linked, there is specifically a check for whether or not markers are present - but for whatever reason that check is ORed with the check for fill instead of ANDed. Seems to me the right logic there would be to make that a logical AND. It would seem that if markers were added by the user, the user would generally expect them to be shown in their entirety even in the case where a fill tozeroy was occurring.

@cldougl
Copy link
Member

cldougl commented Sep 11, 2017

right- looking at the code there is a check if markers are added but that is over-ridden if the fill goes to y-zero

@petergaultney
Copy link
Author

petergaultney commented Sep 11, 2017

Additionally, I'm seeing similar behavior ('missing' padding along the X axis) even when there is no fill component. I'm actually stumped by this one - I don't see how the code you linked would be causing this to occur.

Look especially at the values at the bottom for 'week2'.

screenshot 2017-09-11 11 30 08

data = list()
for team in last_team_order:
    ys = [100*y for y in teams[team]]
    data.append(
        go.Scatter(
            x = week_names,
            y = ys,
            mode = 'lines+markers',
            line=dict(width=8, color=rgb(div.colors[team][0])),
            marker=dict(size=14, color=rgb(div.colors[team][1]),
                        line=dict(width=3, color=rgb(div.colors[team][0]))),
            name=team,
    ))
layout = go.Layout(
    title='{} {} Weekly Championship Probabilities'.format(confname, div.name),
    showlegend=True,
    yaxis=dict(
        type='linear', range=[0,100],
        dtick=10, ticksuffix='%',
        title='% chance for championship',
    ),
    # margin=go.Margin(pad=10),
    paper_bgcolor=rgb(conf_bgs[confname]),
    plot_bgcolor=rgb(conf_bgs[confname]),
)
fig = go.Figure(data=data, layout=layout)
html_div = plot(fig, include_plotlyjs=False, output_type='div')

You can see by the commented line in my code that I attempted to use go.Margin padding to sort this out, but it did not have any effect.

@cldougl
Copy link
Member

cldougl commented Sep 11, 2017

Adding the hidden trace to prevent the fill to zero y would be a good solution. For your original issue.
We're currently working on updating some of our plot auto-range logic: plotly/plotly.js#1876.
I'll close this issue since any updates or changes would have to occur in our plotly.js library, but I would suggest following along or commenting on the linked plotly.js issue for any updates.

@cldougl
Copy link
Member

cldougl commented Sep 11, 2017

I'm happy to take a look at the x-axis issue: #826 (comment) but it's helpful if you provide a simple and reproducible example (with data) that I can run.

For the first issue, here is a codepen that illustrates the difference between the padding when filling to y-zero vs not filling to zero: https://codepen.io/plotly/pen/xXKrww

@petergaultney
Copy link
Author

I'll see if I can work up that minimal example for you. Thanks for the help so far! My initial experimentation with Plotly has been largely positive - every plotting library has its unexpected edge cases, but I would say that Plotly seems to have fewer than most.

@petergaultney
Copy link
Author

petergaultney commented Sep 11, 2017

Actually, if you change the codepen you provided such that, for trace1, the definition starts like this:

trace1 = {
  x: ['monday', 'tuesday', 'wednesday'], 
  y: [0, 20, 10], 
  // fill: 'tonexty', 
  // fillcolor: 'green', 
...
}

(where the first data point is zero, but no fill is applied)

...then I think you'll have your minimal example for the markers getting cut off along the bottom (and probably top as well?) of the X axis, even though there is now padding along the Y axis.

@cldougl
Copy link
Member

cldougl commented Sep 11, 2017

great, for that you should be able to add cliponaxis = False

https://codepen.io/plotly/pen/EwYLxW

@petergaultney
Copy link
Author

thank you! Hopefully this issue can serve as a breadcrumb trail for anyone else who found themselves in a bit of a documentation gap when trying to get their graphs to look a little nicer. I really appreciate all the help!

@cldougl
Copy link
Member

cldougl commented Sep 12, 2017

great- glad that got worked out for you. Closing the issue (though it's still searchable/a good breadcrumb :) )

@cldougl cldougl closed this as completed Sep 12, 2017
@tRosenflanz
Copy link

tRosenflanz commented Apr 15, 2018

Edit: Nevermind - my yaxis was reversed and I just saw a PR that fixes interactions of cliponaxis and reversed yaxis. Just needed to update the versions

@petergaultney I saw that you have fixed this issue by combining margin.pad and cliponaxis but I can't seem to get it to work in my case with fill='tonexty'. I am working in python but any code snippets will be helpful even if they are in JS...

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