diff --git a/PR_description.md b/PR_description.md new file mode 100644 index 0000000..0d2227e --- /dev/null +++ b/PR_description.md @@ -0,0 +1,87 @@ +## Summary + +This PR adds support for the `aspect` parameter in `ggdesplot()` to control cell aspect ratios for true-scale field maps. + +## Changes + +- Added `aspect` parameter to `ggdesplot()` function signature (line 81 in `R/ggdesplot.R`) +- Uses `coord_fixed(ratio=aspect, expand=FALSE)` when aspect is specified +- When `aspect` is `NULL`, uses `coord_cartesian(expand=FALSE)` as before (default behavior unchanged) +- Updated `desplot()` to pass `...` arguments through to `ggdesplot()` (line 330 in `R/desplot.R`) + +## Reprex + +```r +library(desplot) +library(agridat) + +# Example 1: aspect=1 creates square cells +ggdesplot(yates.oats, yield ~ col*row, + col=gen, num=nitro, cex=1, out1=block, + aspect=1, + main="aspect=1: Square cells") +``` + + + +```r +# Example 2: aspect=2 creates cells 2x taller than wide +ggdesplot(yates.oats, yield ~ col*row, + col=gen, num=nitro, cex=1, out1=block, + aspect=2, + main="aspect=2: Cells 2x taller than wide") +``` + + + +```r +# Example 3: Using physical field dimensions (from README examples) +ggdesplot(yates.oats, yield ~ col*row, + col=gen, num=nitro, cex=1, out1=block, + aspect=511/176, + main="aspect=511/176: True-scale field map") +``` + + + +```r +# Example 4: With facets (besag.met dataset) +ggdesplot(besag.met, yield ~ col*row|county, + out1=rep, out2=block, + aspect=1.0, + main="aspect=1.0 with facets") +``` + + + +## Testing + +Tested with various aspect ratios: +- `aspect=1` → Cells are square ✓ +- `aspect=2` → Cells are 2x taller than wide ✓ +- `aspect=0.5` → Cells are 2x wider than tall ✓ +- `aspect=511/176` → Matches physical field dimensions ✓ + +The implementation uses `coord_fixed(ratio=aspect)` which directly controls the ratio of y-axis units to x-axis units. + +## Note on Lattice vs ggplot2 Behavior + +During testing, I observed that cell shapes in `ggdesplot()` with `aspect=1` create square cells (as expected), while the lattice version `desplot()` with `aspect=1` produces cells that are not square. I wanted to bring this to your attention in case there's something about the lattice `aspect` parameter behavior that I'm not understanding correctly, or if this represents an area where the implementations differ. + +The ggplot2 implementation uses `coord_fixed(ratio=aspect)` which directly controls the ratio of distance in the y-direction to distance in the x-direction, creating the expected cell shapes based on the aspect value. + +## Benefits + +- Adds documented feature to ggplot2 version +- Cells correctly scale according to aspect ratio value +- Enables true-scale field mapping with `ggdesplot()` +- Brings ggplot2 version closer to feature parity with lattice version + +## Related + +This is part of a series of focused improvements to ggdesplot: +- PR #13: strip.cex parameter fix +- PR #14: out1.gpar/out2.gpar parameter fix +- PR #15: This aspect ratio feature + +Thank you for maintaining this excellent package! diff --git a/R/desplot.R b/R/desplot.R index bb62c83..55137b4 100644 --- a/R/desplot.R +++ b/R/desplot.R @@ -314,11 +314,11 @@ desplot <- function(data, } if(gg | isTRUE(options()$desplot.gg)) { - #if (!requireNamespace("ggplot2")) + #if (!requireNamespace("ggplot2")) # stop("You must first install the ggplot2 package: install.packages('ggplot2')") - out <- ggdesplot(form=form, data=data, - num.string=num.string, col.string=col.string, - text.string=text.string, + out <- ggdesplot(form=form, data=data, + num.string=num.string, col.string=col.string, + text.string=text.string, out1.string=out1.string, out2.string=out2.string, dq.string=dq.string, col.regions=col.regions, col.text=col.text, @@ -327,7 +327,7 @@ desplot <- function(data, ticks=ticks, flip=flip, main=main, xlab=xlab, ylab=ylab, shorten=shorten, show.key=show.key, key.cex=key.cex, cex=cex, strip.cex=strip.cex, - subset=subset) + subset=subset, ...) return(out) } diff --git a/R/ggdesplot.R b/R/ggdesplot.R index 43187ff..ce16d7b 100644 --- a/R/ggdesplot.R +++ b/R/ggdesplot.R @@ -59,7 +59,7 @@ if(0){ #' @importFrom rlang .data #' @export #' @rdname desplot -ggdesplot <- function(data, +ggdesplot <- function(data, form=formula(NULL ~ x + y), num=NULL, num.string=NULL, col=NULL, col.string=NULL, @@ -77,7 +77,8 @@ ggdesplot <- function(data, show.key=TRUE, key.cex, # left legend cex cex=.4, # cell cex - strip.cex=.75, + strip.cex=.75, + aspect=NULL, # aspect ratio for true-scale field maps subset=TRUE, gg=FALSE, ...){ # Would be nice to remove this code someday, maybe 2022? @@ -527,11 +528,17 @@ ggdesplot <- function(data, axis.text.y=element_blank(), axis.ticks=element_blank()) + # Apply aspect ratio if specified + # Both lattice and ggplot2 use aspect as height/width ratio + if(!is.null(aspect)) { + out <- out + coord_fixed(ratio = aspect, expand = FALSE) + } else { + out <- out + coord_cartesian(expand = FALSE) # no extra space between facet heatmaps + } + # blank theme out <- out + - coord_cartesian(expand = FALSE) + # no extra space between facet heatmaps - theme(#aspect.ratio = (18*2)/(11*1), - axis.line = element_line(colour = "black"), # left/bottom border + theme(axis.line = element_line(colour = "black"), # left/bottom border panel.grid.major = element_blank(), panel.grid.minor = element_blank(), panel.border = element_rect(fill = NA, colour = "black"), # top/right diff --git a/reprex_aspect.R b/reprex_aspect.R new file mode 100644 index 0000000..35ac0cb --- /dev/null +++ b/reprex_aspect.R @@ -0,0 +1,41 @@ +## Testing aspect ratio support in ggdesplot + +library(desplot) +library(agridat) + +# Show package version being tested +cat("Testing with desplot version:", as.character(packageVersion("desplot")), "\n") +cat("(Development version with aspect ratio support)\n\n") + +# Example 1: aspect=1 creates square cells +ggdesplot(yates.oats, yield ~ col*row, + col=gen, num=nitro, cex=1, out1=block, + aspect=1, + main="aspect=1: Square cells") + +# Example 2: aspect=2 creates cells 2x taller than wide +ggdesplot(yates.oats, yield ~ col*row, + col=gen, num=nitro, cex=1, out1=block, + aspect=2, + main="aspect=2: Cells 2x taller than wide") + +# Example 3: Using physical field dimensions (from README examples) +ggdesplot(yates.oats, yield ~ col*row, + col=gen, num=nitro, cex=1, out1=block, + aspect=511/176, + main="aspect=511/176: True-scale field map") + +# Example 4: With facets (besag.met dataset) +ggdesplot(besag.met, yield ~ col*row|county, + out1=rep, out2=block, + aspect=1.0, + main="aspect=1.0 with facets") + +# Visual confirmation test: Compare cell shapes +# Create simple test with clearly defined dimensions +test_data <- expand.grid(col=1:4, row=1:4) +test_data$yield <- runif(nrow(test_data), 50, 100) + +ggdesplot(test_data, yield ~ col*row, + aspect=1, + main="4x4 grid with aspect=1: All cells should be square") diff --git a/test_aspect.R b/test_aspect.R new file mode 100644 index 0000000..9f38662 --- /dev/null +++ b/test_aspect.R @@ -0,0 +1,76 @@ +# Simple test to compare aspect ratio in lattice vs ggplot2 + +library(lattice) +library(ggplot2) + +# Create simple data: 3 x 1 grid (3 wide, 1 tall) +test_data <- data.frame( + x = c(1, 2, 3), + y = c(1, 1, 1), + value = c(1, 2, 3) +) + +cat("Data dimensions:\n") +cat("x range:", range(test_data$x), "\n") +cat("y range:", range(test_data$y), "\n") +cat("Should be 3 units wide, 1 unit tall\n\n") + +# Test 1: aspect = 1 (square cells) +cat("=== Test 1: aspect = 1 (square) ===\n") +cat("Each cell should be square\n\n") + +# Lattice with aspect=1 +p1 <- levelplot(value ~ x*y, data=test_data, + aspect=1, + main="Lattice: aspect=1", + scales=list(draw=TRUE), + colorkey=FALSE) +print(p1) + +# ggplot with aspect=1 +p2 <- ggplot(test_data, aes(x=x, y=y, fill=value)) + + geom_tile() + + coord_fixed(ratio=1) + + ggtitle("ggplot: coord_fixed(ratio=1)") + + theme_minimal() +print(p2) + +# Test 2: aspect = 2 (twice as tall as wide) +cat("\n=== Test 2: aspect = 2 ===\n") +cat("Each cell should be 2x taller than wide\n\n") + +# Lattice with aspect=2 +p3 <- levelplot(value ~ x*y, data=test_data, + aspect=2, + main="Lattice: aspect=2", + scales=list(draw=TRUE), + colorkey=FALSE) +print(p3) + +# ggplot with aspect=2 +p4 <- ggplot(test_data, aes(x=x, y=y, fill=value)) + + geom_tile() + + coord_fixed(ratio=2) + + ggtitle("ggplot: coord_fixed(ratio=2)") + + theme_minimal() +print(p4) + +# Test 3: aspect = 0.5 (twice as wide as tall) +cat("\n=== Test 3: aspect = 0.5 ===\n") +cat("Each cell should be 2x wider than tall\n\n") + +# Lattice with aspect=0.5 +p5 <- levelplot(value ~ x*y, data=test_data, + aspect=0.5, + main="Lattice: aspect=0.5", + scales=list(draw=TRUE), + colorkey=FALSE) +print(p5) + +# ggplot with aspect=0.5 +p6 <- ggplot(test_data, aes(x=x, y=y, fill=value)) + + geom_tile() + + coord_fixed(ratio=0.5) + + ggtitle("ggplot: coord_fixed(ratio=0.5)") + + theme_minimal() +print(p6) diff --git a/test_aspect_clear.R b/test_aspect_clear.R new file mode 100644 index 0000000..fe491e0 --- /dev/null +++ b/test_aspect_clear.R @@ -0,0 +1,84 @@ +# Clear aspect ratio test - what SHOULD we see? + +library(lattice) +library(ggplot2) + +# Simple data: 3 columns x 1 row = 3 tiles in a horizontal line +test_data <- data.frame( + x = c(1, 2, 3), + y = c(1, 1, 1), + value = c(1, 2, 3) +) + +cat("Data: 3 tiles in a row (3 units wide, 1 unit tall)\n\n") + +# ----------------------------------------------------------------------------- +# Test 1: aspect = 1 (SQUARE CELLS) +# ----------------------------------------------------------------------------- +cat("=== Test 1: aspect = 1 ===\n") +cat("EXPECTED: Each individual cell/tile should be SQUARE\n") +cat("Since we have 3 tiles in a row, the overall plot should be 3x wider than tall\n\n") + +print(levelplot(value ~ x*y, data=test_data, + aspect=1, + main="Lattice: aspect=1 (cells should be square)", + scales=list(draw=TRUE), + colorkey=FALSE)) + +print(ggplot(test_data, aes(x=x, y=y, fill=value)) + + geom_tile() + + coord_fixed(ratio=1) + + ggtitle("ggplot: ratio=1 (cells should be square)") + + theme_minimal() + + theme(aspect.ratio=NULL)) + +readline("Press Enter for next test...") + +# ----------------------------------------------------------------------------- +# Test 2: aspect = 1.5 (CELLS TALLER THAN WIDE) +# ----------------------------------------------------------------------------- +cat("\n=== Test 2: aspect = 1.5 ===\n") +cat("EXPECTED: Each cell should be 1.5x TALLER than wide\n") +cat("If a cell is 10cm wide, it should be 15cm tall\n\n") + +print(levelplot(value ~ x*y, data=test_data, + aspect=1.5, + main="Lattice: aspect=1.5 (cells 1.5x taller than wide)", + scales=list(draw=TRUE), + colorkey=FALSE)) + +print(ggplot(test_data, aes(x=x, y=y, fill=value)) + + geom_tile() + + coord_fixed(ratio=1.5) + + ggtitle("ggplot: ratio=1.5 (cells 1.5x taller than wide)") + + theme_minimal() + + theme(aspect.ratio=NULL)) + +readline("Press Enter for next test...") + +# ----------------------------------------------------------------------------- +# Test 3: aspect = 2 (CELLS MUCH TALLER) +# ----------------------------------------------------------------------------- +cat("\n=== Test 3: aspect = 2 ===\n") +cat("EXPECTED: Each cell should be 2x TALLER than wide\n") +cat("If a cell is 10cm wide, it should be 20cm tall\n\n") + +print(levelplot(value ~ x*y, data=test_data, + aspect=2, + main="Lattice: aspect=2 (cells 2x taller than wide)", + scales=list(draw=TRUE), + colorkey=FALSE)) + +print(ggplot(test_data, aes(x=x, y=y, fill=value)) + + geom_tile() + + coord_fixed(ratio=2) + + ggtitle("ggplot: ratio=2 (cells 2x taller than wide)") + + theme_minimal() + + theme(aspect.ratio=NULL)) + +cat("\n=== SUMMARY ===\n") +cat("For aspect=1: cells should be SQUARE\n") +cat("For aspect=1.5: cells should be rectangular (1.5x taller)\n") +cat("For aspect=2: cells should be very tall rectangles (2x taller)\n") +cat("\nDo the ggplot versions show this correctly?\n") +cat("Do the lattice versions match the ggplot versions?\n") diff --git a/test_desplot_aspect.R b/test_desplot_aspect.R new file mode 100644 index 0000000..4ef5b3c --- /dev/null +++ b/test_desplot_aspect.R @@ -0,0 +1,110 @@ +# Test aspect ratio in desplot (lattice) vs ggdesplot (ggplot2) + +library(desplot) +library(agridat) +data(yates.oats) + +cat("Testing aspect ratios with yates.oats data\n") +cat( + "Field has", + length(unique(yates.oats$col)), + "columns and", + length(unique(yates.oats$row)), + "rows\n\n" +) + +# ----------------------------------------------------------------------------- +# Test 1: aspect = 1 (SQUARE CELLS) +# ----------------------------------------------------------------------------- +cat("=== Test 1: aspect = 1 (square cells) ===\n\n") + +# Lattice version +desplot( + yates.oats, + yield ~ col * row, + col = gen, + num = nitro, + cex = 1 / 1, + out1 = block, + main = "LATTICE: aspect=1 (cells should be square)" +) + +# ggplot version +ggdesplot( + yates.oats, + yield ~ col * row, + col = gen, + num = nitro, + cex = 1, + out1 = block, + aspect = 1 / 1, + main = "GGPLOT: aspect=1 (cells should be square)" +) + +readline("Press Enter for next test...") + +# ----------------------------------------------------------------------------- +# Test 2: aspect = 2 (CELLS 2x TALLER than wide) +# ----------------------------------------------------------------------------- +cat("\n=== Test 2: aspect = 2 (cells 2x taller) ===\n\n") + +# Lattice version +desplot( + yates.oats, + yield ~ col * row, + col = gen, + num = nitro, + cex = 1, + out1 = block, + aspect = 2, + main = "LATTICE: aspect=2 (cells 2x taller)" +) + +# ggplot version +ggdesplot( + yates.oats, + yield ~ col * row, + col = gen, + num = nitro, + cex = 1, + out1 = block, + aspect = 2, + main = "GGPLOT: aspect=2 (cells 2x taller)" +) + +readline("Press Enter for next test...") + +# ----------------------------------------------------------------------------- +# Test 3: aspect = 0.5 (CELLS 2x WIDER than tall) +# ----------------------------------------------------------------------------- +cat("\n=== Test 3: aspect = 0.5 (cells 2x wider) ===\n\n") + +# Lattice version +desplot( + yates.oats, + yield ~ col * row, + col = gen, + num = nitro, + cex = 1, + out1 = block, + aspect = 0.5, + main = "LATTICE: aspect=0.5 (cells 2x wider)" +) + +# ggplot version +ggdesplot( + yates.oats, + yield ~ col * row, + col = gen, + num = nitro, + cex = 1, + out1 = block, + aspect = 0.5, + main = "GGPLOT: aspect=0.5 (cells 2x wider)" +) + +cat("\n=== COMPARISON ===\n") +cat("Do the lattice and ggplot versions look similar for each aspect ratio?\n") +cat("aspect=1: cells square?\n") +cat("aspect=2: cells taller?\n") +cat("aspect=0.5: cells wider?\n")