GangCaoLab / CoolBox

Jupyter notebook based genomic data visualization toolkit.
https://gangcaolab.github.io/CoolBox/index.html
GNU General Public License v3.0
227 stars 37 forks source link

Allowing XAxis() to show lengths in bp in addition to kb #50

Closed c-guzman closed 2 years ago

c-guzman commented 3 years ago

Currently running

frame = XAxis() + \
        BedGraph(bdg_path) + \
        Color("black") + TrackHeight(2) + Title("5' MPRA (Original Pool Rep1)")

Results in a image (https://imgur.com/a/1FWN0ZQ) where the x axis is shown as all 0's because my sequences are less than 1000bp. I am unable to find a way to change this so that the x axis is shown in bp instead of kb.

Is this something that is changeable, if so how? And if not, would it be possible to include this for small sequences?

c-guzman commented 3 years ago

For anyone interested in doing this, I solved this by modifying the XAxis() code a bit to allow for this:

class XAxis1(Track):
    """
    The x axis track.
    Parameters
    ----------
    height : float, optional
        Height of Spacer track. (Default: XAxis.DEFAULT_HEIGHT)
    fontsize : int, optional
        Font size of XAxis. (Default: XAxis.DEFAULT_FONTSIZE)
    where : {'top', 'bottom'}, optional
        The position of tick labels relative to the axis.
        (Default: 'bottom')
    name (str, optional):
        Track's name.
    """

    DEFAULT_PROPERTIES = {
        "where": "bottom",
        "height": 2,
        "fontsize": 15,
    }

    def __init__(self, **kwargs):
        properties = XAxis.DEFAULT_PROPERTIES.copy()
        properties.update(kwargs)
        super().__init__(properties)

    def fetch_data(self, gr: GenomeRange, **kwargs):
        pass

    def plot(self, ax, gr: GenomeRange, **kwargs):
        self.ax = ax

        ax.set_xlim(gr.start, gr.end)
        ticks = ax.get_xticks()

        if ticks[-1] - ticks[1] <= 1000:
            labels = ["{:.0f}".format((x))
                      for x in ticks]
            labels[-2] += " bp"

        elif ticks[-1] - ticks[1] <= 1e5:
            labels = ["{:,.0f}".format((x / 1e3))
                      for x in ticks]
            labels[-2] += " Kb"

        elif 1e5 < ticks[-1] - ticks[1] < 4e6:
            labels = ["{:,.0f}".format((x / 1e3))
                      for x in ticks]
            labels[-2] += " Kb"
        else:
            labels = ["{:,.1f} ".format((x / 1e6))
                      for x in ticks]
            labels[-2] += " Mbp"

        ax.axis["x"] = ax.new_floating_axis(0, 0.5)

        ax.axis["x"].axis.set_ticklabels(labels)
        ax.axis['x'].axis.set_tick_params(which='minor', bottom='on')

        ax.axis["x"].major_ticklabels.set(size=int(self.properties['fontsize']))

        if 'where' in self.properties and self.properties['where'] == 'top':
            ax.axis["x"].set_axis_direction("top")
Nanguage commented 2 years ago

This has been added to XAxis's code. https://github.com/GangCaoLab/CoolBox/commit/08a211a3a532277956970e59caf5e6d8cf12f2df Thanks!