2
votes

I have a set of data that I want to make a log scale graph of, I want the Y axis of my graph to be a log10 scale and the X a normal time series.

I've tried various ways from various graphs I have found on the internet and also from this website, but none of them seems to work the way I want to, either giving an empty graph, not showing the axis (just the label), or even giving an empty png file.

library(ggplot2)
library(MASS)
library(scales)

# assume everything happens in GMT timezone
Sys.setenv( TZ = "GMT" )
# replicating the data: a measurement result sampled at 1 sec interval
t <- seq(start, end, by = "1 sec")
Time24 <- trimws(strftime(t, format = "%k:%M:%OS", tz="GMT"))
Date <- strftime(t, format = "%d/%m/%Y", tz="GMT")
head(Time24)
head(Date)
d <- data.frame(Date, Time24)
d$temp <- rnorm(length(d$Date),mean=25,sd=5)
head(d)
# the resulting data is as follows
#        Date  Time24     temp
#1 22/05/2019 0:00:00 22.67185
#2 22/05/2019 0:00:01 19.91123
#3 22/05/2019 0:00:02 19.57393
#4 22/05/2019 0:00:03 15.37280
#5 22/05/2019 0:00:04 31.76683
#6 22/05/2019 0:00:05 26.75153


# combining the the date and the time column of the data
t <- as.POSIXct(paste(d$Date,d$Time24,sep=" "), format = "%d/%m/%Y %H:%M:%OS", tz="GMT")

# Log Scale Method 1
png(filename = "Method 1.png", width = 800, height = 600, units = "px", pointsize = 22 )
ggplot(df,aes(x=t,y=Temp)) + geom_line() +
  scale_x_datetime(name="Time",date_breaks = "2 hour",
                   date_labels = "%H:%M\n%d-%b") +

  # Log Scale transformation code 1
  scale_y_continuous(trans = "log10") +

  labs(title="Method 1", y="Temperature (C)") +
  theme(plot.title = element_text(hjust = 0.5, size = 20),
        axis.title.x = element_text(size = 18),
        axis.title.y = element_text(size = 18),
        axis.text.x = element_text(size=14),
        axis.text.y = element_text(size=14))

# Log Scale Method 2
png(filename = "Method 2.png", width = 800, height = 600, units = "px", pointsize = 22 )

# Log Scale transformation code 2
ggplot(df,aes(x=t,y=Temp), log10="y") + geom_line() +

  scale_x_datetime(name="Time",date_breaks = "2 hour",
                   date_labels = "%H:%M\n%d-%b") +
  labs(title="Method 2", y="Temperature (C)") +
  theme(plot.title = element_text(hjust = 0.5, size = 20),
        axis.title.x = element_text(size = 18),
        axis.title.y = element_text(size = 18),
        axis.text.x = element_text(size=14),
        axis.text.y = element_text(size=14))

# Log Scale Method 3
png(filename = "Method 3.png", width = 800, height = 600, units = "px", pointsize = 22 )
ggplot(df,aes(x=t,y=Temp)) + geom_line() +
  scale_x_datetime(name="Time",date_breaks = "2 hour",
                   date_labels = "%H:%M\n%d-%b") +

  # Log Scale tranfsormation code 3
  scale_y_log10(breaks = trans_breaks("log10", function(x) 10^x),
                labels = trans_format("log10", math_format(10^.x))) +

  labs(title="Method 3", y="Temperature (C)") +
  theme(plot.title = element_text(hjust = 0.5, size = 20),
        axis.title.x = element_text(size = 18),
        axis.title.y = element_text(size = 18),
        axis.text.x = element_text(size=14),
        axis.text.y = element_text(size=14))

# Log Scale Method 4
png(filename = "Methpd 4.png", width = 800, height = 600, units = "px", pointsize = 22 )
ggplot(df,aes(x=t,y=Temp)) + geom_line() +
  scale_x_datetime(name="Time",date_breaks = "2 hour",
                   date_labels = "%H:%M\n%d-%b") +

  # Log Scale transformation code 4
  scale_y_continuous(formatter='log10')

  labs(title="Method 4", y="Temperature (C)") +
  theme(plot.title = element_text(hjust = 0.5, size = 20),
        axis.title.x = element_text(size = 18),
        axis.title.y = element_text(size = 18),
        axis.text.x = element_text(size=14),
        axis.text.y = element_text(size=14))



quit()

I wanted the Y axis to show both the scaling and the tick labels of a log10 like this:

Expected Outcome

but instead I've produced these results from the various method I've tried:

Result of the first method

Result of the second method

Result of the third method

Result of the fourth method

The first part of the code is just a place holder for my dataset which I understand I cannot post here in the form of a csv, and I do not know how else to post my code and make it a perfect reproducible outcome, I am quite new to R, and especially ggplot2, I apologize for any mistakes and shortcomings, thanks in advance.

2
What are your start and end variables?heds1
can you manually create a log version of your xvalues then use them?morgan121
@RAB No, but for what purpose do I want to create a log version of my x values?Hanif Shidki

2 Answers

2
votes

tl;dr the range of your data (approx. 23-27) is too small to effectively use a log scale. You can set the breaks manually (see method #2 below), in which case it looks like ggplot is not respecting your request for a log-scaled axis, but the difference between a linear and a log scale is almost indistinguishable for this data range.

Set up data:

set.seed(101)
dd <- data.frame(x=seq.Date(as.Date("2019-01-01"),as.Date("2019-01-31"), by="1 day"), 
   y = runif(31,min=23,max=27))
dd2 <- transform(dd,y=c(25,runif(29,min=23,max=27),27000))

Method 1: no axis ticks, as above

library(ggplot2)
(gg1 <- ggplot(dd,aes(x,y))+geom_point()+scale_x_date()+scale_y_log10())
gg1 %+% dd2

Method 2: manually specified axis breaks (essentially the same as your method 2)

(gg2 <- ggplot(dd,aes(x,y))+geom_point()+scale_x_date()+scale_y_log10(breaks=23:27))
gg2 %+% dd2 + scale_y_log10(breaks=c(23,100,5000,27000))
0
votes

It is as simple as changing the y axis on your graph.

# use ggplot
library(ggplot2)
# assume everything happens in GMT timezone
Sys.setenv( TZ = "GMT" )

# make the data, ideal logarithmic response
x = seq(1,1000)
y = 1200*exp(-x/300)

# add time data
time.start=as.POSIXct("2016-01-04 16:00",format="%Y-%m-%d %H:%M")
time.end = time.start + 999
x.time = seq(time.start, time.end, by = "1 sec")

df = data.frame(x,y,x.time)

# print linear plot
png(filename = "linear.png", width = 800, height = 600, units = "px", pointsize = 22 )
ggplot(df,aes(x=x.time,y=y)) + geom_point() +
  scale_x_datetime(limits = c(time.start,time.end),
                   date_breaks = "10 mins",
                   date_minor_breaks = "2 mins",
                   date_labels = "%H:%M\n%d-%b")
dev.off()

# print log plot
png(filename = "log.png", width = 800, height = 600, units = "px", pointsize = 22 )
ggplot(df,aes(x=x.time,y=y)) + geom_point() +
  scale_x_datetime(limits = c(time.start,time.end),
                   date_breaks = "10 mins",
                   date_minor_breaks = "2 mins",
                   date_labels = "%H:%M\n%d-%b") +
  scale_y_continuous(trans = 'log10')

dev.off()

Note the scale_y_continuous(trans = 'log10') function.

Here are the resulted graphs.

linear plot

log plot