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

Auto axis scaling #165

Merged
merged 64 commits into from
Oct 26, 2023
Merged

Auto axis scaling #165

merged 64 commits into from
Oct 26, 2023

Conversation

dan-knight
Copy link
Contributor

@dan-knight dan-knight commented Oct 19, 2023

Description

Closes #156. These changes improve documentation and refactor internal package code around automatic axis scaling. This functionality has existed in several plotting functions with auto.axis(), but was difficult to discover. These changes focus on a the most straightforward axis scaling use cases - only a handful of plotting functions:

  • create.scatterplot
  • create.barplot
  • create.boxplot
  • create.hexbinplot
  • create.manhattanplot

Vignette Section

The scale at which data is viewed is extremely impactful to the insight that can be drawn from a visualization. While linear scaling is perfectly fine, some datasets are more easily interpreted after log transforming the data, for example.

6.4.1 Automatic Axis Scaling

BPG supports automatic axis scaling for several plot types with the auto.axis function. This functionality can be accessed through the xat and yat parameters when calling a plotting function. There are 3 settings to choose from:

  • auto.log: log10 scaled, with automatically spaced and formatted tick locations.-
  • auto.linear: Linear scaled, with automatic tick placement based on analysis of the data. ❼ auto: Automatically chooses the most appropriate setting (auto.log or auto.linear).
    If nothing is passed, the plot will use lattice’s default axis creation method, which is often less ”pretty” than BPG’s automatic axes.
Screenshot 2023-10-20 at 5 52 23 PM

6.4.2 Manual Axis Scaling

It’s possible to manually scale the axes for use cases not supported by auto.axis. This is a three step process:

  • Transform the data.
  • Transform the axis tick locations in xat and yat to match the data transformation.
  • Override the axis tick labels in xaxis.lab and yaxis.lab to correspond to the pre-transformation values from the data.

Vignette Plot Examples

This also includes a new section in the Plotting Guide vignette about axis scaling, plus examples in some plot sections
Screenshot 2023-10-20 at 3 52 56 PM
Screenshot 2023-10-20 at 4 04 02 PM
Screenshot 2023-10-20 at 5 48 22 PM
Screenshot 2023-10-20 at 5 49 25 PM

Checklist

  • This PR does NOT contain PHI or germline genetic data. A repo may need to be deleted if such data is uploaded. Disclosing PHI is a major problem.

  • This PR does NOT contain molecular files, compressed files, output files such as images (e.g. .png, .jpeg), .pdf, .RData, .xlsx, .doc, .ppt, or other non-plain-text files. To automatically exclude such files using a .gitignore file, see here for example.

  • I have read the code review guidelines and the code review best practice on GitHub check-list.

  • I have set up or verified the main branch protection rule following the github standards before opening this pull request.

  • The name of the branch is meaningful and well formatted following the standards, using [AD_username (or 5 letters of AD if AD is too long)]-[brief_description_of_branch].

  • I have added the major changes included in this pull request to the NEWS under the next release version or unreleased, and updated the date. I have also updated the version number in DESCRIPTION according to semantic versioning rules.

  • Both R CMD build and R CMD check run successfully.

dan-knight and others added 30 commits October 9, 2023 09:58
…ic-R-BoutrosLab-plotting-general into shipit-auto-axis
Add parameter `which.arg` to `prep.axis` to disambiguate between `xat`
and `yat` in error messages in the event of invalid input.
Correct what data are overwritten in `create.boxplot` when `prep.axis`
is called on the x-axis and returns a list.
…trosLab-plotting-general into shipit-auto-axis
Use `prep.axis` in `create.scatterplot` (and `create.lollipopplot`).
…trosLab-plotting-general into shipit-auto-axis
…trosLab-plotting-general into shipit-auto-axis
DESCRIPTION Outdated
Type: Package
Title: Functions to Create Publication-Quality Plots
Date: 2023-10-09
Date: 2023-10-18
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is now the 24th.

NEWS Outdated
@@ -1,3 +1,14 @@
BoutrosLab.plotting.general 7.1.0 2023-10-18
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Date here also.

x = data.frame(test.data$z, rnorm(10))
);

# # This is the slowest running function
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove commented code.

Copy link
Member

@aholmes aholmes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me, just update the release dates.

Copy link
Contributor

@tyamaguchi-ucla tyamaguchi-ucla left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nicely done! Looks good to me! I've made some minor corrections/suggestions and added feature requests. Anything else to add @jarbet ?

If nothing is passed, the plot will use lattice’s default axis creation method, which is often less ”pretty” than BPG’s automatic axes.

I think it would be nice to use the auto as default once we stabilize the feature.

man/auto.axis.Rd Outdated Show resolved Hide resolved
R/auto.axis.R Outdated Show resolved Hide resolved
}

return(out);
}

generate.at <- function(min.x, max.x, pretty = TRUE, include.origin = TRUE, num.labels = 4) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Feature request] It might be useful to make this function available. (no need to worry about it in this PR)

}

return(out);
}


as.power10.expression <- function(x) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Feature request] It would be useful to make this function officially available. (no need to worry about it in this PR) I think this issue is related #73

skewness.x <- skewness(x, na.rm = TRUE);
# Handle zero values so that they can still be plotted even log(0) = -Inf
zero.i <- which(0 == x);
logx <- log(x, 10);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Feature Request] We might want to accept log2 as well (no need to worry about it in this PR)

Copy link
Contributor Author

@dan-knight dan-knight Oct 24, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We might want to accept log2 as well (no need to worry about it in this PR)

Definitely! We intend to add this, probably by parsing anything after auto.log as the base of the log (so xat = auto.log2).

@dan-knight
Copy link
Contributor Author

I think it would be nice to use the auto as default once we stabilize the feature.

Agree. We didn't want to change any defaults in this release, but we really liked auto and think it should eventually be the default.

dan-knight and others added 2 commits October 24, 2023 15:41
Co-authored-by: Takafumi Yamaguchi <62572751+tyamaguchi-ucla@users.noreply.github.com>
dan-knight and others added 4 commits October 24, 2023 15:41
Co-authored-by: Takafumi Yamaguchi <62572751+tyamaguchi-ucla@users.noreply.github.com>
…trosLab-plotting-general into shipit-auto-axis
@dan-knight dan-knight requested a review from aholmes October 24, 2023 23:18
Copy link
Contributor

@jarbet jarbet left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! 3 comments:

  1. How can we view the vignette? devtools::build_vignettes didn't work, and utils::browseVignettes said there are no vignettes
  2. I'm echoing @tyamaguchi-ucla comment about eventually supporting log2, since many people in the lab use log2 for effect sizes
  3. Can the auto.log method be used to make a -log10 p-value barplot? This is a very common application in the lab. I had trouble getting the auto.log to make the right plot, maybe I am using it wrong. Here is the plot I have in mind:
suppressPackageStartupMessages(library(BoutrosLab.plotting.general));

set.seed(123);
n <- 5;
dataset <- data.frame(pvalue = runif(n, 0, 0.0001), gene = letters[1:n]);
dataset$mlog10.pvalue <- -log10(dataset$pvalue);

xat <- 0:max(round(dataset$mlog10.pvalue));

xaxis.lab <- sapply( 
    X = xat, 
    FUN = function(x) { 
        if (x == 0) { 
            return(expression(bold('10'^'0'))); 
        } else { 
            return(as.expression(bquote(bold('10'^-.(as.character(x)))))); 
            }
        }
    ); 

create.barplot(
    formula = gene ~ mlog10.pvalue,
    data = dataset,
    plot.horizontal = TRUE,
    xat = xat,
    xlimits = c(min(xat), max(xat)),
    xaxis.lab = xaxis.lab
    )

Created on 2023-10-25 by the reprex package (v2.0.1)

}
out <- prep.axis(
at = xat,
data = unlist(data[toString(formula[[3]])]),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure what formula is but 3 looks like a magic number, more examples below

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm. formula is just the formula argument to the function. These lines just extract the second half of the argument.

Now that you point this out, I don't think this is 100% bulletproof. It will likely break with any formula with a more complex left side. That problem is probably outside the scope of this PR, though. It would require a refactor with some sort of utility function like get.formula.args that accounts for more edge cases.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The table of contents and page numbers are not displaying. Is this just a problem with github or an actual bug?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Weird! Fixed.

Comment on lines 396 to 397
x ~ y,
log.data,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't mix named and positional arguments, use formula = and data = throughout

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, looks like this is enforced across all examples. Fixed.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, looks like this is enforced across all examples. Fixed.

Need to update for create.barplot.Rd, otherwise looks good!

@tyamaguchi-ucla
Copy link
Contributor

3. Can the auto.log method be used to make a -log10 p-value barplot? This is a very common application in the lab. I had trouble getting the auto.log to make the right plot, maybe I am using it wrong. Here is the plot I have in mind:

Yeah, we see this application a lot. Alternatively, we could also use -log10(Q or P Value) as xlabel like this https://www.nature.com/articles/nature20788/figures/2

Comment on lines 396 to 397
x ~ y,
log.data,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, looks like this is enforced across all examples. Fixed.

Need to update for create.barplot.Rd, otherwise looks good!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like Figure 67 got moved to the wrong section, it should be in 6.1:

image

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems to be an issue with the Sweave .Rnw format. This issue occurs in multiple places, and doesn't seem to relate to the placement of the code in the .Rnw file. You can find it in the the current CRAN release. Sweave seems to try to arrange the figures in an "optimal" way rather than just adhering to the order in the code. This is part of the reason I think we should move this to .Rmd format, as it seems to render more consistently.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems to be an issue with the Sweave .Rnw format. This issue occurs in multiple places, and doesn't seem to relate to the placement of the code in the .Rnw file. You can find it in the the current CRAN release. Sweave seems to try to arrange the figures in an "optimal" way rather than just adhering to the order in the code. This is part of the reason I think we should move this to .Rmd format, as it seems to render more consistently.

Ahh interesting. Got it!

@dan-knight dan-knight merged commit 348a561 into main Oct 26, 2023
3 checks passed
@dan-knight dan-knight deleted the shipit-auto-axis branch October 26, 2023 22:17
@dan-knight dan-knight mentioned this pull request Apr 29, 2024
7 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Refactor code to prepare xat and yat
6 participants