The visualizations mentioned in this blog post are based on the idea of Elana Levin and her article describing drawing portraits using bar charts in the Datawrapper tool. She used Processing to work with images and data.

In this article, I will use Python to get data and Tableau to visualize the received data.

The main idea here is to build images using bar charts. This is a non-common use of this type of chart, and this method is not needed in business tasks, but such tasks allow you better understand Tableau and try to work with the Pillow library in Python.

1. Image preparation

In order to prepare an image for transformation into data, you need to get the original image and resize it in a graphics editor so that the number of pixels horizontally and vertically corresponds to the number of points that you want to display on the visualization. Each point will correspond to one bar.

I found pictures of actors who have no Oscars here

After that I selected 10 actors and reduced the photo of each one to 100×120 pixels. You can do this in MS Paint. Let’s take a photo of Eddie Murphy and resize it:

Save the .png file.

2. Converting photos to data

Each bar on the visualization will represent one pixel, and the bar length will represent the brightness of this pixel, so we need to get a dataset with the coordinates of all pixels and their brightness. For this we use Python:

from PIL import Image
import numpy as np
import csv
import os

# open picture as greyscale pic, creating an array
img = np.array(Image.open("C:\\Docs\\Bar Portraits\\Murphy.png").convert('L'))
def csvWriter(fil_name, nparray):
    example = nparray.tolist()
    with open(fil_name+'.csv', 'w', newline='') as csvfile:
        writer = csv.writer(csvfile, delimiter=',')
        writer.writerows(example)

# write data to csv
csvWriter("C:\\Docs\\Bar Portraits\\Murphy_temp", img)

# numerate rows
with open("C:\\Docs\\Bar Portraits\\Murphy_temp.csv", 'r') as read_object, open("C:\\Docs\\Bar Portraits\\Murphy.csv", 'w') as write_object:
    for idx, line in enumerate(read_object, start=1):
        write_object.write('{}, {}'. format(idx, line))

# remove temp file
os.remove("C:\\Docs\\Bar Portraits\\Murphy_temp.csv")

Note: in the code, replace the path to the working directory on your computer.

As a result, we get a data matrix with numbered rows:

In this table, the values in column A are the row numbers, and the values in the remaining columns are the brightness values. The maximum brightness value is 255. The size of the table is the same as the size of the picture, and in our case it is 100×120. That is, each cell in the table contains information about the brightness of the corresponding pixel.

3. Drawing portraits in Tableau

Let’s connect the .csv file to Tableau. We get the following table:

Do the pivot operation on all columns except the first one:

Split the Pivot Field Names column, leave only the column with numeric values and rename the columns:

The data is ready for visualizing!

Create the calculation Brightness_actual:

255 – [Brightness]

Make the portrait:

The portrait is done.

In fact, the visualization itself is a 100×120 table, each cell of which contains one bar with a length equal to the brightness at that point.

You can change the types of Marks, use colors to get other forms of images. For example, if we select circles on the marks shelve and put in the color Brightness_actual, we get the following:

You can add more photos to your dataset using Union and enable animation to transform photos. The example below shows changing the position of pixels on photos and transform them into pixels in other photos. For this, additional calculations are used.

You can experiment a lot of course, and the result will please you anyway.

My final viz allows you to adjust the brightness by increasing and decreasing the bar length, there is also the ability to switch to different types of marks

Клик для перехода