R Lesson 31: Logarithmic Graphs

Hello everybody,

Michael here, and today’s lesson will be a sort-of contiuation of my previous post on R logarithms (R Lesson 30: Logarithms). However, in this post, I’ll cover how to create logarithmic graphs in R.

Let’s begin!

Two types of log plots

There are two main types of logarithmic plots in R-logarithmic scale plots and log-log plots.

What do these log plots do, exactly? Well, in the case of the logarithmic scale plot, only one of the plot’s axes uses a logarithmic scale while the other maintains a linear scale while with the log-log plot both axes use logarithmic scales.

When would you use each type of plot? In the case of logarithmic scale plots, you’d use them for analyses such as exponential growth/decay or percentage changes over a period of time. As for the log-log plots, they’re better suited for analyses such as comparative analyses (which involve comparing datasets with different scales or units) and data where both the x-axis and y-axis have a wide range of values.

And now for the logarithmic scale plots!

Just as the header says, let’s create a logarithmic scale plot in R!

Before we begin, let’s be sure we have the necessary data that we’ll use for this analysis-

This dataset is simpler than most I’ve worked with on this blog, as it only contains 11 rows and two columns. Here’s what each column means:

  • Date-the date that the bitcoin mining reward will be halved
  • Reward-the amount of bitcoin you will recieve after a successful mining as of the halving date.

For those unfamiliar with basic Bitcoin mining, the gist of the process is that when you mine Bitcoin you get a reward. However, after every 3-4 years, the reward for mining bitcoin is halved. For instance, on the first ever day that you could mine bitcoin (January 1, 2009), you would be able to recieve 50 bitcoin (BTC) for a successful haul. In 2012, the reward was halved to 25 BTC for a successful haul. The next halving is scheduled to occur in Spring 2024, where the reward will be halved to 3.125 BTC. Guess bitcoin mining isn’t as profitable as it was nearly 15 years ago?

There will likely be no more Bitcoin left to mine by the year 2140, so between now and then, the Bitcoin mining reward will get progressively smaller (a perfect example of exponential decay). I did mention that the Bitcoin mining reward will be less than 1 BTC by the year 2032.

  • I mean, don’t take my word for it, but maybe the supply of mineable bitcoin won’t run out by 2140 and the reward instead would get progressively smaller until it’s well over 1/1,000,000,000th of 1 BTC. Just my theory though :-).

Now, enough about the Bitcoin mining-let’s see some logarithmic scale plots! Take a look at the code below.

First, we’ll read in our dataset:

bitcoin <- read.csv("C:/Users/mof39/OneDrive/Documents/bitcoin halving.csv", encoding="utf-8")

Next, we’ll create our logarithmic scale plot! Since there is only one axis that will use a log-scale (the y-axis in this case), let’s remember to specify that

plot(bitcoin$Date, bitcoin$Reward, log = "y", pch = 16, col = "blue", xlab = "Year", ylab = "BTC Reward")

Error in plot.window(...) : need finite 'xlim' values
In addition: Warning messages:
1: In xy.coords(x, y, xlabel, ylabel, log) : NAs introduced by coercion
2: In min(x) : no non-missing arguments to min; returning Inf
3: In max(x) : no non-missing arguments to max; returning -Inf

If we tried to use the plot() function along with all the parameters specified here, we’d get this error-Error in plot.window(...) : need finite 'xlim' values. Why does this occur?

The simple reason we got the error is because we used a column with non-numeric values for the x-axis. How do we fix this? Let’s create a numeric vector of the years in the Reward column (with the exception of 2009, all of the years in the Reward column are leap years until 2080) and use that vector as the x-axis:

years <- c(2009, 2012, 2016, 2020, 2024, 2028, 2032, 2036, 2040, 2044, 2048, 2052, 2056, 2060, 2064, 2068, 2072, 2076, 2080)

plot(years, bitcoin$Reward, log = "y", pch = 16, col = "red", xlab = "Year", ylab = "BTC Reward", main = "BTC Rewards 2009-2080")

Voila! As you can see here, we have a nice log-scale plot showing the exponential decay in bitcoin mining rewards from 2009 to 2080.

How did create this nice-looking plot? Well, we set the value of the log parameter of the plot() function equal to y, as we are only creating a log-scale plot. If we wanted to create a log-log plot, we would se the value of the log parameter to xy, which would indicate that we would use a logarithmic scale for both the x and y axes.

As for the rest of the values of the parameters in the plot() function, keep them the same as you would for a normal, non-logarithmic R scatter plot (except of course adapting your x- and y-axes and title to fit the scatterplot).

Now, one thing I did want to address on this graph is the scale on the y-axis, which might look strange to you if you’re not familiar with log-scale plots. See, the plot() function’s log parameter in R uses base-10 logs by default, and in turn, the y-axis will use powers of 10 in the scale (the scientific notation makes the display a little neater). For instance, 1e+01 represents 10, 1e+00 represents 0, and so on. Don’t worry, all the data points in the dataset were plotted correctly here.

And now, let’s create a log-log plot

Now that we’ve created a log-scale plot, it’s time to explore how to create a log-log plot in R!

loglog <- data.frame(x=c(2, 4, 8, 16, 32, 64), y=c(3, 9, 27, 81, 243, 729))

plot(loglog$x, loglog$y, log = "xy", pch = 16, col = "red", xlab = "Power of 2", ylab = "Power of 3", main = "Sample Log-Log Plot")

In this example, I created the dataframe loglog and filled both axes with powers of 2 and 3 to provide a simple way to demonstrate the creation of log-log plots in R.

As for the plot() function, I made sure to set the value of the log parameter to xy since we’re creating a log-log plot and thus need both axes to use a logarithmic scale. Aside from that, remember to change the plot’s axes, labels, and titles as appropriate for your plot.

Now, you might’ve noticed somthing about this graph. In R, both log-log and log-scale plots utilize base-10 logs for creating the plot. However, you likely noticed that the scale for the log-scale plot displays its values using scientific notation and powers of 10. The scale (or should I say scales) for the log-log plot doesn’t use scientifc notation and powers of 10 to display its values. Rather, the log-log plot uses conventional scaling to display its values-in other words, the scale for the log-log plot bases its values of the range of values in both axes rather than a powers-of-10 system. Honestly, I think this makes sense since the plot is already using a logarithmic scale for both axes, which would make the whole powers-of-10 thing in the scale values redundant.

  • Of course, if you want to change the scale displays in either the log-log or log-scale plots, all you would need to do is utilize the axis() function in R after creating the plot. Doing so would allow you to customize your plot’s axis displays to your liking.

Thnaks for reading!

Michael

R Lesson 30: Logarithms

Hello everybody,

Michael here, and I hope you had a little fun with my two-part fifth anniversary post (particularly the puzzle). For the next several posts, we’ll be exploring more mathematics with R. Today we’ll discuss the wonderful world of R logarithms (and logarithms in general).

But first, a word on logarithms

As you may have noticed from my previous R mathematics posts, I always explain the concept in both the context of R and the context of manual calculation so you can have a basic understanding of the concept itself before exploring it in R. I plan to do the same thing here today.

So, what are logarithms exactly? They’re simply another type of mathematical operation. Take a look at this illustration below:

In this example, I used the simple example of 4^3=64. I also noted that the logarithmic form of this expression is log4(64)=3.

What does this mean? The base of the exponentional expression (4^3=64)-4-serves at the base of the logarithm. The number in parentheses-64-serves as the logarithm’s argument, which is the value used to find the logarithm’s exponent (or result), which is 3 in this case.

How do you read a logarithmic expression? In this example, you’d read the expression as log base-4 of 64 equals 3.

That’s how logarithms work. Now let’s explore how to manage them in R.

Logarithms, R style

So, how would you work with logarithms in R? Let’s take a look at the code below:

> log(32, base=2)
[1] 5

Calculating logs in R is as simple as using R’s built-in log() function and adding in two parameters-the argument and the base. With these two parameters and the log() function, R will return the logarithm’s exponent, which in this case is 5 since log base-2 of 32 equals 5.

However, what I discussed above was a very, very basic example of logarithms in R. Let’s look a more specific scenario:

> log10(1000)
[1] 3

In this example, I’m showing what is known as a base-10 logarithm, which is a logarithm with a base of, well, 10. In this case, I’m showing you what log base-10 of 1000 equals-in this case, the exponent/result is 3. Notice how this expression uses the log10() function rather than the log() function.

  • NOTE: To calculate this base-10 logarithm you can also use the code log(1000, base=10), but I just wanted to point out the log10() function as another way to solve a logarithm.

Another specific logarithmic scenario is binary, or base-2 logarithms. Let’s take a look at those:

> log2(8)
[1] 3

In this example, I’m showing a base-2 logarithm, which is a logarithm with a base of, well, 2. In this case, the base-2 log of 8 is 3, since 2^3=8.

  • NOTE: Just like the case with the base-10 logarithm, you can also use the code log(8, base=2) to calculate this base-2 algorithm.

Now let’s explore two rather unusual logarithmic scenarios-logarithms of imaginary numbers and logarithms with base e (e as in the mathematical constant). What does it all mean? Let me explain!

> log(11)
[1] 2.397895

> log(3+2i, base=4)
[1] 0.9251099+0.4241542i

The first example above shows the expression log base-e of 11 along with the result, 2.397895. The second example shows the expression log base-4 of 3+2i along with the result, 0.9251099+0.4241542i.

If you’re not familiar with the concept of imaginary numbers and the mathematical constant e, fear not, for I will explain both concepts right here!

A rational section about some irrational numbers

If you have even the most basic knowledge of numbers, you’ll be quite familiar with the numbers 0-9. After all, when you first learned basic counting, you very likely learned how to count to 10.

However, if you study more advanced math (like alegbra and calculus), you’ll notice there are a few numbers that aren’t so neat (and no, I’m not talking about decimals, fractions or negative numbers). These are known as irrational numbers, which are non-terminating, non-repeating numbers that can’t be expressed as simple fractions or decimals.

We just explored calculating logarithms with two types of irrational numbers-e and imaginary numbers. How do these types of numbers work?

In the case of e, e is a mathematical constant known as Euler’s number-named after Swiss mathematician Leonhard Euler. e is an irrational number that stretches on for infinity, but its approximate value is 2.71828. The number e is used in various exponential growth/decay functions, such as a city’s population growth/decline over a certain time period or a substance’s radioactive decay.

A log with a base e is also known as a natural logarithm (like the log(11) example I used earlier). In R, natural logarithms are denoted as log(number) with no base parameter specified. Here’s what natural logarithms look like:

In the case of the imaginary numbers, such as 3+2i, they provide an easy way to handle complex mathematical situations, such as the square roots of negative numbers (which will always be imaginary numbers). Imaginary numbers always consist of a real part multiplied by the imaginary unit i (such as 2i). The number 3+2i is known as a complex imaginary number since it has a real part (3) and an imaginary part (2i). One well known application of imaginary numbers is fractal geometry, which you can find quite a bit of in nature (like in conch shells).

Three more logarithmic scenarios that I think you should know

Before I go, I want to discuss three more logarithmic scenarios with you all, first with natural logs and then with logs that have a numerical base. Take a look at the code below:

> log(1)
[1] 0
> log(0)
[1] -Inf
> log(-12)
[1] NaN
Warning message:
In log(-12) : NaNs produced

In this example, I’m showing you three different natural logarithm scenarios that you should know-logs with arguments of 1, 0, and a negative number. Notice that a log with an argument of 1 yields 0, an log with an argument of 0 yields negative infinity and a log with a negative number yields an NaN (indicating that logs with negative arguments aren’t valid). Why might this be the case?

  • In the case of log(1), you get 0 because raising a number to the power of 0 always yields 1.
  • In the case of log(0), you get -Inf (negative infinity) because there is no possible power you can raise e to obtain 0.
  • In the case of log(-12), you get NaN (not a number) because logs only work with positive number arguments.

Now here are three scenarios with the same arguments, but using a base of 2 instead of e:

> log(1, base=2)
[1] 0
> log(0, base=2)
[1] -Inf
> log(-12, base=2)
[1] NaN
Warning message:
NaNs produced 

Notice how you get the same results here as you did for the natural logarithms.

Thanks for reading,

Michael