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

Manipulating plotly dendrograms #789

Closed
scottkleinman opened this issue Jun 26, 2018 · 7 comments
Closed

Manipulating plotly dendrograms #789

scottkleinman opened this issue Jun 26, 2018 · 7 comments

Comments

@scottkleinman
Copy link
Contributor

scottkleinman commented Jun 26, 2018

The Plotly API for dendrograms is underdeveloped, so about the only way to fix the appearance is to modify the SVG after the Ajax response is written to the DOM. Here are some practical thoughts about some of the problems:

Vertical labels get cut off

I've only tested to see if this is the case for bottom orientation, so my solution is targeted towards that scenario. Basically, you just need to enlarge the plot with the following:

if ($('#orientation option:selected').attr('value') === 'bottom') {
  $('.plotly-graph-div, .svg-container').css('height', '1100px')
  $('.main-svg').att('height', '1100')
}

The extra 100 pixels was good for a 21-character label and probably more.

Labels change orientation

This happens when you zoom in and out and seems to be a response to the available horizontal space. I don't know how to override it.

Ticks and labels separate from dendrogram leaves

This happens when you zoom out so that the dendrogram is not the full height (assuming bottom orientation) of the bordered container. Ticks are on the border and labels outside the container, so the only way to fix the problem would be to scale the container with the dendrogram. I don't think that is worth it. Short of checking whether zoom out is making the dendrogram smaller than the container and preventing it, I think we just have to live with this.

Rightmost dendrogram leaf is too close to bordered frame

It is relatively easy to move the dendrogram to the left as follows:

if ($('#orientation option:selected').attr('value') === 'bottom') {
  $('.plot').attr('transform', 'translate(25 100)')
}

However, the ticks and labels have to be moved separately. This can be done manually for an existing plot by trial and error, but I have no idea how we would calculate the values to do it automatically. It's worth investigating, but we'd really have to get into the weeds of how svg transforms work.

A different option — one I haven't tried yet — would be to extend the border frame to the right (for a bottom-oriented dendrogram) without moving the dendrogram. Or perhaps to eliminate the top, right, and maybe bottom borders altogether, leaving just the y-axis ticks to measure height. This might be a lot easier. If we still wanted a border frame around the plot, we can do it in the container div.

@mleblanc321
Copy link
Contributor

@danny98m -- take a shot at some of these suggestions

@scottkleinman
Copy link
Contributor Author

@danny98m To implement something like my last suggestion, where you remove parts of the frame, you can do this in dendro_model.py. Replace

figure['layout'].update({'width': 800, 'height': 1000,
                          'hovermode': 'x'})

with

figure['layout'].update({'width': 800, 'height': 1000,
                        'hovermode': 'x',
                        'xaxis': {'linewidth': 0, 'mirror': False},
                        'yaxis': {'mirror': False}
                        })

This will get rid of the top and right border. I'm not yet sure how to get rid of the bottom border. But once that's done, the graph can be put in a box by adding a border to the container div.

@scottkleinman
Copy link
Contributor Author

scottkleinman commented Jun 28, 2018

OK, here's my next experiment. In dendrogram.html add style="border: 1px solid #444; padding: 5px;" to <div id="dendrogram-result" class="row">. This will put a border around the plot.

Now replace the code in dendro_model.py described above with

figure['layout'].update({'width': 800, 'height': 1000,
                                'hovermode': 'x',
                                'xaxis': {'mirror': False, 'showline': False},
                                'yaxis': {'mirror': False}
                        })

(I'm not actually sure if you need mirror: False with showline: False, but it doesn't hurt.)

How does this look to everyone?

@scottkleinman
Copy link
Contributor Author

scottkleinman commented Jun 28, 2018

At least for bottom orientation, Plotly seems to display the final leaf in the dendrogram as 1 pixel wide instead of 2. This is pretty ugly. Here is a hack to fix, although it is definitely a hack. After the plot is added to the DOM from the Ajax response with $('#dendrogram-result').html(response), add the following:

const path = $('.plot').find('path').first()
const split = path.attr('d').split(",")
const lastLeaf = split[2].split("L")
const adjust = parseInt(lastLeaf[1]) - 1
const lastLeafLine = lastLeaf[0] + 'L' + adjust.toString()
const coords = [split[0], split[1], lastLeafLine, lastLeafLine, split[4]].join()
path.attr('d', coords)

Basically, this just finds the SVG path, parses the coordinates to find the number that needs to be adjust by 1, and then re-writes the coordinates back to the path's d attribute.

Update: Unfortunately, this effect does not survive changes in the zoom level; we'd have to add it in a callback whenever zoom in or zoom out is triggered.

@Weiqi97
Copy link
Member

Weiqi97 commented Jul 27, 2018

From Plotly's GitHub repo, I found this PR, which suggests that using automargin will resolve the long label cuts off issue at least for Cartesian Plane. I replaced lines

figure['layout'].update({'width': 800, 'height': 1000, 'hovermode': 'x'})

with

figure['layout'].update(
    {
        'width': 800, 
        'height': 1000,
        'hovermode': 'x',
        'xaxis': {'automargin': True},
        'yaxis': {'automargin': True}
    }
)

But, very strange, that did not work. I will update once I get more output.

@Weiqi97
Copy link
Member

Weiqi97 commented Jul 31, 2018

#811 fixed vertical label cut off issue and rightmost leaf is too closed to plot border issue.

@Myles-Trevino
Copy link
Contributor

This seems to be sufficiently mitigated in the current implementation of dendrogram.

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

No branches or pull requests

6 participants