Can You Tell Free Python Art from Multi-Million Dollar Pieces?
Follow along for a Python generative art tutorial, inspired by Piet Mondrian and Josef Albers. From Code to Canvas, Part I.Which are the three real pieces? Image by Author. Piet Mondrian’s works are Public Domain. An artwork falls into the public domain 70 years after the death of the artist.One of these pieces has been generated by Python and the rest are Piet Mondrian originals. Which one is the odd one out? I’ll give you the answer a few paragraphs down but first I need to tell you why I am using Python for art generation and not a fancy Gen-AI tool.As a creative art enthusiast born with zero artistic skills, I saw the launch of DALL-E and others as the opportunity to cover my entire flat in “my” masterpieces without needing to master a brush.That wasn't the case and my walls remain a blank canvas. I didn’t manage to create anything display-worthy, but most importantly — DALL-E killed the vibe.Why?Because most of the magic in art comes from feeling our way through the creative process. It’s a journey — not just an outcome. AI art felt too dictated, too random, and too cold for me.So that got me thinking: is there a sweet middle spot? Is there a way to have random but controlled generative art and still get that dopamine/pride moment of a finished piece? And needless to say, without actual artistic skills?In this article I will show you how I created two museum-worthy art pieces, and we will uncover which is the Mondrian impostor.How to create Piet Mondrian fakesFor my first Generative Art piece, I’ve taken inspiration from Piet Mondrian, a pioneer of abstract art. His work is presented as an abstract arrangement of lines, colours and shapes.Here is a little sample of some of his most iconic pieces:Image created by Author. Piet Mondrian’s work is Public Domain.Do you know which one is the impostor already?If you’re interested in giving it a try, you just have to install the “mondrian-maker” Python package to paint new pieces like this:The mondrian-maker package was created by Andrew Bowen and is published under a GNU General Public License.from mondrian_maker.mondrian import mondrianm = mondrian()m.make_mondrian()Composition generated by AuthorPart of the fun is that a new piece will be generated every time you call make_mondrian(). Not all of them will be “painting-worthy” so I generated 100 and chose my favourites.for i in range(0,100): f,ax=m.make_mondrian() f.savefig(f"{i}_mondrian.png")And the answer to the Python or original game? The impostor is the third one from the left????. The rest of the pieces are (from left to right): Composition No. I with Red and Blue (1938); Composition with Red, Yellow and Blue (1942); Composition No.10 (1939)Puzzle solution!. Image generated by Author. Piet Mondrian’s work is Public DomainDid you guess right? Let me know in the comments!Keep reading if you want to know how to recreate another thousand-dollar art piece:Josef Albers — Homage to the SquareWhile Mondrian’s work really caught my attention, I wanted to start from scratch and make something of my own. That’s why I turned to Josef Albers’ Homage to the Square series. I am drawn to the way he played with perspective and colour, plus there’s something about the “simple” look that felt like the right place to dive in. Judge by yourself:https://medium.com/media/6fdac2de1988e07f4011c6edec9d9222/hrefNow, before we start drawing squares, there are two key secrets for Python generative art that you should know:Reproducibility: We want our art to be random but also to be able to generate the exact painting again. By using numpy.random.seed() we can make sure that random numbers remain the same across different runs.import numpy as npconstant=12np.random.seed(constant)# From now on all generated random numbers are reproducible if constant=12# To get different random numbers, choose a new constantColour theory: Artists use combinations of colours to generate visually appealing colour palettes. The coding secret for this is to use MetBrewer, a Python library that contains 56 beautiful palettes inspired by works at the Metropolitan Museum of Art in New York.Screenshot from MetBrewer (Creative Commons License)from met_brewer import met_brewpalette=met_brew(name="Hokusai3", brew_type="discrete")????Now we are ready to start painting!????Spoiler alert: the next blocks of code reveal how to create an Homage to the Square lookalike painting, skip them if you prefer to try it yourself first.1- I first build a function that generates the following:The 4 edges of a square (x0,x1,y0,y1)A random colour for each squarefrom numpy import randomdef rectangle_generator(palette): rectangle=[] big={'x0': 0, 'y0': 0, 'x1': 1, 'y1': 1,'color':palette[random.randint(len(palette))]} rectangle.append(big) middle={'x0': 0.1, 'y0': 0.05, 'x1': 0.9, 'y1': 0.85,'color':palette[random.randint(len(palette))]} rectangle.append(middle) small={'x0': 0.2, 'y0': 0.1, 'x1': 0.8, 'y1': 0.7,'color':palette[random.randint(len(palette
Follow along for a Python generative art tutorial, inspired by Piet Mondrian and Josef Albers. From Code to Canvas, Part I.
One of these pieces has been generated by Python and the rest are Piet Mondrian originals. Which one is the odd one out? I’ll give you the answer a few paragraphs down but first I need to tell you why I am using Python for art generation and not a fancy Gen-AI tool.
As a creative art enthusiast born with zero artistic skills, I saw the launch of DALL-E and others as the opportunity to cover my entire flat in “my” masterpieces without needing to master a brush.
That wasn't the case and my walls remain a blank canvas. I didn’t manage to create anything display-worthy, but most importantly — DALL-E killed the vibe.
Why?
Because most of the magic in art comes from feeling our way through the creative process. It’s a journey — not just an outcome. AI art felt too dictated, too random, and too cold for me.
So that got me thinking: is there a sweet middle spot? Is there a way to have random but controlled generative art and still get that dopamine/pride moment of a finished piece? And needless to say, without actual artistic skills?
In this article I will show you how I created two museum-worthy art pieces, and we will uncover which is the Mondrian impostor.
How to create Piet Mondrian fakes
For my first Generative Art piece, I’ve taken inspiration from Piet Mondrian, a pioneer of abstract art. His work is presented as an abstract arrangement of lines, colours and shapes.
Here is a little sample of some of his most iconic pieces:
Do you know which one is the impostor already?
If you’re interested in giving it a try, you just have to install the “mondrian-maker” Python package to paint new pieces like this:
The mondrian-maker package was created by Andrew Bowen and is published under a GNU General Public License.
from mondrian_maker.mondrian import mondrian
m = mondrian()
m.make_mondrian()
Part of the fun is that a new piece will be generated every time you call make_mondrian(). Not all of them will be “painting-worthy” so I generated 100 and chose my favourites.
for i in range(0,100):
f,ax=m.make_mondrian()
f.savefig(f"{i}_mondrian.png")
And the answer to the Python or original game? The impostor is the third one from the left????. The rest of the pieces are (from left to right): Composition No. I with Red and Blue (1938); Composition with Red, Yellow and Blue (1942); Composition No.10 (1939)
Did you guess right? Let me know in the comments!
Keep reading if you want to know how to recreate another thousand-dollar art piece:
Josef Albers — Homage to the Square
While Mondrian’s work really caught my attention, I wanted to start from scratch and make something of my own. That’s why I turned to Josef Albers’ Homage to the Square series. I am drawn to the way he played with perspective and colour, plus there’s something about the “simple” look that felt like the right place to dive in. Judge by yourself:https://medium.com/media/6fdac2de1988e07f4011c6edec9d9222/href
Now, before we start drawing squares, there are two key secrets for Python generative art that you should know:
- Reproducibility: We want our art to be random but also to be able to generate the exact painting again. By using numpy.random.seed() we can make sure that random numbers remain the same across different runs.
import numpy as np
constant=12
np.random.seed(constant)
# From now on all generated random numbers are reproducible if constant=12
# To get different random numbers, choose a new constant
- Colour theory: Artists use combinations of colours to generate visually appealing colour palettes. The coding secret for this is to use MetBrewer, a Python library that contains 56 beautiful palettes inspired by works at the Metropolitan Museum of Art in New York.
from met_brewer import met_brew
palette=met_brew(name="Hokusai3", brew_type="discrete")
????Now we are ready to start painting!????
Spoiler alert: the next blocks of code reveal how to create an Homage to the Square lookalike painting, skip them if you prefer to try it yourself first.
1- I first build a function that generates the following:
- The 4 edges of a square (x0,x1,y0,y1)
- A random colour for each square
from numpy import random
def rectangle_generator(palette):
rectangle=[]
big={'x0': 0, 'y0': 0, 'x1': 1, 'y1': 1,'color':palette[random.randint(len(palette))]}
rectangle.append(big)
middle={'x0': 0.1, 'y0': 0.05, 'x1': 0.9, 'y1': 0.85,'color':palette[random.randint(len(palette))]}
rectangle.append(middle)
small={'x0': 0.2, 'y0': 0.1, 'x1': 0.8, 'y1': 0.7,'color':palette[random.randint(len(palette))]}
rectangle.append(small)
tiny={'x0': 0.3, 'y0': 0.15, 'x1': 0.7, 'y1': 0.55,'color':palette[random.randint(len(palette))]}
rectangle.append(tiny)
return rectangle
2- I then plotted each square coordinate with Plotly
import plotly.graph_objects as go
import plotly.express as px
import numpy as np
from met_brewer import met_brew
import plotly.io as pio
#For reproducibility
np.random.seed(73)
#Choose a beautiful palette from met_brewer
palette=met_brew(name="Morgenstern", n=30,brew_type="continuous")
# Generate rectangles with defined palette
rectangles=rectangle_generator(palette)
# Plot!
# Setting canvas
fig=go.Figure()
fig.update_layout(
autosize=False,
width=800,
height=800,
)
fig.update_xaxes(range=[0, 1], showgrid=False,visible=False)
fig.update_yaxes(range=[0, 1],visible=False)
# Start painting
for rect in rectangles:
fig.add_shape(
type="rect",
x0=rect['x0'],y0=rect['y0'],
x1=rect['x1'],y1=rect['y1'],
line=dict(color=rect['color'],
width=2,),
fillcolor=rect['color']
)
fig.update_shapes(dict(xref='x', yref='y'))
fig.show()
pio.write_image(fig, "73morgensternplot.png", format="png", width=800, height=800, scale=3)
And here’s the final result!
Let me tell you why I truly enjoyed designing this art piece — and why I hope that you do too:
First, I had to crack the code on the square dimensions, making sure they matched the original piece’s perspective. Then came the fun (and slightly obsessive) part: playing with colour palettes waiting for that magical “aha” moment when everything just clicked.
I didn’t stop there. I generated over 100 paintings with different seed constants, basically becoming my own art curator and finding “the one”.
The best part? I got to skip hours of painting frustration only to end up with something “okayish.” And, I wasn’t let down by an overhyped Gen-AI tool. Instead, I let my imagination run and came out with a piece I’d proudly hang on my wall — or even buy.
In my opinion, art looks elevated and more expensive with a frame on:
This is the first article of a new series: From Code to Canvas. I’m open to suggestions on Art pieces you’d like to code-recreate so feel free to leave a comment! And don’t forget to follow — your empty walls will thank you.
All images in this article are by the author except for Piet Mondrain’s works which are Public Domain.
Can You Tell Free Python Art from Multi-Million Dollar Pieces? was originally published in Towards Data Science on Medium, where people are continuing the conversation by highlighting and responding to this story.