Using Cellular Automata and Climate Data to Generate Visual Art

After the recording of the first demo with my band Mundo Kumo where we create music inspired on per reviewed papers about climate change, it was time to create some of the videos that we will be using on our live show. My initial idea was to use computer generated art combined with real climate data. I had experience with coding and complex artificial intelligence algorithms however not much experience using artificial intelligence (AI) to generate art.

The code used here was developed using the python language and it can be downloaded freely on my github repository called AlgorithmicArt. Although this was the initial idea about the videos,  the idea changed a lot after and we are not using all the videos explained here. However they are still a really good starting point.

When doing a little bit of research on the topic i found that Cellular automata was probably one of the easiest way to start. The concept of cellular automata was created by the mathematician Stephen Wolfram and some of the rules are very similar to the majority vote model used widely on statistical mechanics.

The first intuitive step is the use of the one-dimensional cellular automata (the easiest to implement and understand) . Thus picking a cellular automaton rule, it is possible to create a picture similarly to the pictures found on the internet.



To make things a little bit more interesting, a video can be made showing the evolution of the cellular automata grouping sequential gifs. This can be done using different alternatives. For example using ubuntu and the imagemagick package:

convert -delay 20 -loop 0 *.jpg myimage.gif

The final video is a thing like this:

The second step is to add the climate information in the code and combine with the cellular automata. I used global temperature anomalies from NOAA. I maped the colors based on the range of temperature anomalies. Thus, the colors (global temperature anomalies) and the evolution of the cellular automata are connected:

Next post I will talk about two-dimensional cellular automata.


Think Python AND R and not just PYTHON OR R: Creating vectors

In this post I will talk a little bit about how python and R work with vectors. I am using python 2.7.13 and R 3.4.3, both 64-bit on a Ubuntu 16.04 and I am also using the free book called A Hands-On Introduction to Using Python in the Atmospheric and Oceanic Sciences by prof. Johnny Lin as a guide.

Creating vectors

The first thing about a vector is how to create one. There are several ways to create a vector in R. For example, if one needs to create a logical vector:

a = vector(mode = "logical", length = 5)
c = rep(FALSE,5)

or a numerical vector:

a = vector(mode = "numeric", length = 5)
b = c(0, 0, 0, 0, 0)
c = rep(x=0, 5)
## [1] 0 0 0 0 0
## [1] 0 0 0 0 0
## [1] 0 0 0 0 0

The vector() function produces a vector of the given length and mode, the c() function is a generic function which combines its arguments and rep() function replicates the values in x also returning a vector.

In python we can use the numpy package which has lots of methods to create and manipulate arrays/vectors. Thus importing the package numpy and generating the same vectors in python:

import numpy as np
a = np.array([False,False,False,False])
b = np.full(4, False, bool)
print a 
print b
## [False False False False]
## [False False False False]

or a numerical vector:

import numpy as np
a = np.array([0,0,0,0])
b = np.full(4, 0, float)
print a
print b
## [0 0 0 0]
## [ 0.  0.  0.  0.]

Why are they different? Remember the dynamical typing? Vector a is a vector of integers and b is a vector of float. The attribute dtype gives the data-type of the array’s elements:

c = np.array([0.0,0.0,0.0,0.0])
print a.dtype  
print b.dtype
print c 
print c.dtype
## int64
## float64
## [ 0.  0.  0.  0.]
## float64

Indexing Vectors

One major difference between python and R is how they address the element in the vector. In python the element addresses start with zero, so the first element of vector a is a[0], the second is a[1], etc.

import numpy as np
d = np.array(range(1,5))
print d
print d[0], d[3] 
## [1 2 3 4]
## 1 4

In R the element addresses follows the ordinal value thus starting from one. Consequently the first element of vector a is a[1], the second is a[2], etc.

d = seq(4)
cat(d[1], d[4], sep=" ")
## [1] 1 2 3 4
## 1 4

Be careful!!!!

Python and R have the same method range() but they do different things. In python range() returns a list containing an arithmetic progression of integers. range(i, j) returns ([i, i+1, i+2,\ldots , j-1]) and the default is i=0.

f = range(5)
g = range(2,5)
print f
print g
## [0, 1, 2, 3, 4]
## [2, 3, 4]

In R the methods similar to range() are seq(), seq_along(), seq_len() (please check the R documentation to see the differences between them) which generates regular sequences. However the default starting value is 1.

f = seq(5)
g = seq(2,5)
## [1] 1 2 3 4 5
## [1] 2 3 4 5

The method range() in R returns a vector containing the minimum and maximum of all the given arguments.

## [1] 1 5
## [1] 5 5

If you have any question, suggestion or opinion about this post please feel free to write a comment below.

Think Python AND R and not just PYTHON OR R: From NULL to String types

Continuing the saga of types in python and R, in this short post i will talk briefly about the NULL object (or NoneType in python) and how python and R handle the String type. I am using python 2.7.13 and R 3.3.3, both 64-bit on Ubuntu 16.04 and I am also using the free book called A Hands-On Introduction to Using Python in the Atmospheric and Oceanic Sciences by prof. Johnny Lin as a guide.

The NULL/None type

The NoneType in python and the NULL object in R are basically used to signify the absence of a value in many situations. It is often returned by expressions and functions whose value is undefined.  Because variables are dynamically typed, objects with value NULL can be changed by replacement operators and will be coerced to the type of the right-hand side. This object is also good to “safely” initialize a parameter, making sure to set the variable to a real value later.
For example, to initialize a variable to NULL (or None in python), and if later on the code tries to do an operation with the variable before the variable has been reassigned to a non-Null Type (or non-NoneType in python) variable, the interpreter will give an error.

In addition because NULL (None) is a special type (object) it has a relational operator to test if an object is NULL (or None). Using R:

a = NULL
a == NULL
## logical(0)
## [1] TRUE

And using pyhton:

a = None
print a == None
print a is None
## True
## True

In python it is possible to use the common relational operator == but it is not recommended. One should use is instead of ==. More information about why here and an example here.

String variables

In python or R string variables (character vectors) are created by setting text in either paired single or double quotes.
Python uses the operator (+) to join strings together:

a = "Hello"
b = "World"
print a 
print b 
print a + b 
## Hello
## World
## HelloWorld

However R does not use the same operator. There are diffrent forms to concatenate strings in R and one of the simplest way is to use the functions paste() (by default includes a space caracther between the strings but this can be easily changed) or paste0().

## [1] "Hello World"
## [1] "HelloWorld"

If you have any question, suggestion or opinion about this post please feel free to write a comment below.

Think Python AND R and not just PYTHON OR R: basic operators could generate different results

Nowadays, probably the two most used programming languages for machine learning are python and R. Both have advantages and disadvantages. With tools like rpy2 or Jupyter with the IRKernel, it is possible to integrate R and python into a single application and make them “talk” with each other. However, it is important to know how they work individually before the connection of these two programming languages. I will try to show some of the similarities and differences between the commands, functions and environment. For example, both languages could have very similar commands but these commands could lead to different results.

There are hundreds books about python and R with different flavours. Basic, advanced, applied, how to, free, paid, master, ninja, etc. Because I used a lot of programming applied to real world scenario I randomly biased decided to, use as a initial guide, a free book called A Hands-On Introduction to Using Python in the Atmospheric and Oceanic Sciences by prof. Johnny Lin (the main idea is to reproduce a machine learning portable code so i will change the reference later). Thus I will follow some examples of this book and give the insights about the python/R relation.

Nevertheless, It is imperative to know what version of the programming language one is using. Commands, types, syntax, can change over versions. Here I am using python 2.7.13 and R 3.2.2, both 64-bit on a Ubuntu 16.04.

Basic operators

In R, the elementary arithmetic operators are the usual +, -, *, / and ^ for raising to a power. The only difference to python is the exponentiation operator which is **.

Basic variables

Python and R are dynamically typed, meaning that variables take on the type of whatever they are set to when they are assigned. Additionally, the variable’s type can be changed (at run time) without changing the variable name. Lets start with two of the most important basic types: integer and float (called double in R). Here it is possible to see the first few differences between the languages. The integer type from the R documentation:

Integer vectors exist so that data can be passed to C or Fortran code which expects them, and so that (small) integer data can be represented exactly and compactly. Note that current implementations of R use 32-bit integers for integer vectors, so the range of representable integers is restricted to about +/-2*10^9: doubles can hold much larger integers exactly.

There are two integers types in python: plain and long.

Plain integers (also just called integers) are implemented using long in C, which gives them at least 32 bits of precision (sys.maxint is always set to the maximum plain integer value for the current platform, the minimum value is -sys.maxint – 1). Long integers have unlimited precision.

How about the float (or double) types? From both programming languages ultimately how double (or float) precision numbers are handled is down to the CPU/FPU and compiler (i.e. for the machine on which your program is running).

OK lets try a simple example. This example is the same as Example 4 on chapter 3 of our guide book. Lets say we have the following variables:

a = 3.5
b = -2.1
c = 3
d = 4

If we run the operators described above in python we have:

print(a*b) #case 1
print(a*d) #case 2
print(b+c) #case 3
print(a/c) #case 4
print(c/d) #case 5
## -7.35
## 14.0
## 0.9
## 1.16666666667
## 0

Repeating the same steps for R we obtain:

## [1] -7.35
## [1] 14
## [1] 0.9
## [1] 1.166667
## [1] 0.75

On cases 2, 4 and 5 we had different results. On case 4, the difference should be related to the float/double representation. Thus it is expected a difference on precision. However it does not mean that R has less precision than python in this example. It could be only the way R shows the variable to the user. Yes, unfortunately R can mislead you. For example, on case 2 the numbers are technically the but they are shown in a different way. The fact that R shows 14 instead of  14.0 does not mean that the value is integer and not double. Let’s use the functions is.integer() and is.double() to check the type of the variable of the result on case 2.

## [1] FALSE
## [1] TRUE

Remember when the “dynamically typed”? The programming language automatically decides what type a variable is based on the value operation. Again from the python documentation:

Python fully supports mixed arithmetic: when a binary arithmetic operator has operands of different numeric types, the operand with the “narrower” type is widened to that of the other, where plain integer is narrower than long integer is narrower than floating point is narrower than complex. Comparisons between numbers of mixed type use the same rule.

That explains why in case 2 we have a float. You can check using the function isinstance().

print(isinstance( a*c, ( int, long ) ))
print(isinstance( a*c, ( float ) ))
## False
## True

How about case 5? Case 5 is a little bit more interesting. For python we are dealing with 2 integers, thus the result should be integer. That is why we have 0 because python does integer division and returns only the quotient.

print(isinstance( c/d, ( int, long ) ))
print(isinstance( c/d, ( float ) ))
## True
## False

How about R? Here is the reason (from the documentation):

For most purposes the user will not be concerned if the “numbers” in a numeric vector are integers, reals or even complex. Internally calculations are done as double precision real numbers, or double precision complex numbers if the input data are complex.

Thus, it is important to keep this in mind because you can have different results.

Similarities not so similar

As a final remark I’d like to mention about the similarities not so similar of the operator ^ in and python. Yes, python also has the same operator but it is the bitwise XOR  operator, which is different of exponentiation. Click here for more information about bitwise operators in python.

If you have any question, suggestion or opinion about this post please feel free to write a comment below.