1
votes

My data is below.

X <- c(0.01, 0.02, 0.03, 0.04, 0.05, 0.1, 0.2, 0.3, 1, 2, 3) 
Y <- c(0.01, 0.02, 0.03, 0.04, 0.05, 0.1, 0.2, 0.3, 1, 2, 3)

I would like to draw a scatter plot for X vs Y by R package ggplot2. The X axis should be 0.01, 0.02, 0.03, 0.04, ..., 0.09, 0.1, 0.2, 0.3, 0.4, ..., 0.9, 1, 2, 3, 4, 5. The Y axis should also be 0.01, 0.02, 0.03, 0.04, ..., 0.09, 0.1, 0.2, 0.3, 0.4, ..., 0.9, 1, 2, 3, 4, 5. My question is that how can I make the length between any two adjacent points in X axis(also Y axis) the same? For example, the length between 0.01 and 0.02 are the same as the length between 0.1 and 0.2 in X axis.

3
I guess you have to create your own transformation (see here) and hand it to scale_x/y_continuous(trans = "your transformation")Wolfgang Arnold
Hey! Have you checked Chapter 8 of R Graphics Cookbook? It is available for free online via Bookdown. Ch 8 might contain just what you're looking for.zeebrah

3 Answers

1
votes
d <- tibble(X= c(0.01, 0.02, 0.03, 0.04, 0.05, 0.1, 0.2, 0.3, 1, 2, 3) ,
            Y = c(0.01, 0.02, 0.03, 0.04, 0.05, 0.1, 0.2, 0.3, 1, 2, 3))

d %>% ggplot(aes(x=X, y=Y)) +
       geom_point() +
        scale_x_log10() +
        scale_y_log10()

enter image description here

Is this what you want?

0
votes

log transform can be a close solution to what you are looking, but it does not provide the same distance:

df <- data.frame(X=X,Y=Y)
p = ggplot(df,aes(x=X,y=Y))+
  geom_line() + 
  geom_point(size=4) 

p+
  scale_x_continuous(trans = "log10") +
  scale_y_continuous(trans = "log10") 

Please check the below website: It is the same problem for Animals data from MASS: http://www.sthda.com/english/wiki/ggplot2-axis-scales-and-transformations

enter image description here

0
votes

Here is a more elaborative solution, where you cut your data into small bins, create a faceted plot by each bin, and then paste the facets back together..

X <- c(0.01, 0.02, 0.03, 0.04, 0.05, 0.1, 0.2, 0.3, 1, 2, 3) 
Y <- c(0.01, 0.02, 0.03, 0.04, 0.05, 0.1, 0.2, 0.3, 1, 2, 3)

library( data.table )
library( ggplot2 )
plotdata <- data.table( x = X, y = Y )

#create bins to plot
limits <- data.table( from = c(0,0.01,0.1,1,10) )
limits[, to := shift( from, type="lead", fill = Inf ) ]
limits[, bin_name := paste(from, to, sep = "-") ]
#     from    to bin_name
# 1:  0.00  0.01   0-0.01
# 2:  0.01  0.10 0.01-0.1
# 3:  0.10  1.00    0.1-1
# 4:  1.00 10.00     1-10
# 5: 10.00   Inf   10-Inf

#bin plotdata for x and y values by joining
plotdata[ limits, bin_x := i.bin_name, on = .(x >= from, x < to ) ][]
plotdata[ limits, bin_y := i.bin_name, on = .(y >= from, y < to ) ][]

#get factorder right for ordering facets
plotdata[, bin_x.f := forcats::fct_rev( factor( bin_x ) ) ]

#almost what we want, but scales are not right
ggplot( data = plotdata ) +
  geom_point( aes(x = x, y = y ) ) +
  facet_grid( bin_x.f ~ bin_y )

enter image description here

#get facetscales-package from github
## devtools::install_github("zeehio/facetscales")  # <-- run once !
library(facetscales)

#build y scales
scales_y <- list(
  "0.01-0.1" = scale_y_continuous(expand = c(0,0), limits = c(0,0.1), breaks = seq(0,0.1,0.01), labels = c( seq(0,0.09,0.01), "" ) ),
  "0.1-1"    = scale_y_continuous(expand = c(0,0), limits = c(0.1,1), breaks = seq(0.1,1,0.1), labels = c( seq(0.1,0.9,0.1), "" ) ),
  "1-10"     = scale_y_continuous(expand = c(0,0), limits = c(1,10), breaks = seq(1,10,1), labels = c( seq(1,9,1), "" ) )
)
#build x scales
scales_x <- list(
  "0.01-0.1" = scale_x_continuous(expand = c(0,0), limits = c(0,0.1), breaks = seq(0,0.1,0.01), labels = c( seq(0,0.09,0.01), "" ) ),
  "0.1-1"    = scale_x_continuous(expand = c(0,0), limits = c(0.1,1), breaks = seq(0.1,1,0.1), labels = c( seq(0.1,0.9,0.1), "" ) ),
  "1-10"     = scale_x_continuous(expand = c(0,0), limits = c(1,10), breaks = seq(1,10,1), labels = c( seq(1,9,1), "" ) )
)

#now we get
ggplot( data = plotdata ) +
  geom_point( aes(x = x, y = y ) ) +
  facet_grid_sc( rows = vars(bin_x.f), cols = vars(bin_y), scales = list( x = scales_x, y = scales_y ) )+
  theme(
    #remove the facet descriptions completely
    strip.background = element_blank(),
    strip.text = element_blank(),
    #drop space bewteen panels
    panel.spacing = unit(0, "lines"),
    #rotate x_axis labels
    axis.text.x = element_text( angle = 90, hjust = 1, vjust = 0.5 ) 
  )

enter image description here

As you can see, this works, but points that are exact lyon the min/max of a bin get cut off a bit due to the expand = c(0,0) when setting the x and y axis.