<jupyter_start><jupyter_text>*Histograms: Height & Width*<jupyter_code>## Creating a list of 'height' values converted to floats, ignoring any missing or faulty values

height_list = []

for row in metadata_table:
    try:
        height = float(row[23])        # Converting height value (at index 23) to float and assigning it to 'height' variable
        height_list.append(height)     # Adding value to 'height_list'
    except:
        pass                           # If we get an error in the 'try' block above, we do nothing and move to the next row.
                                       # This happens when the 'height' field is empty, so it can't be converted to float.

height_list[:10]      # Viewing first 10 height values
## Creating a list of 'width' values converted to floats, ignoring any missing or faulty values

width_list = []

for row in metadata_table:
    try:
        width = float(row[26])
        width_list.append(width)
    except:
        pass


width_list[:10]
## Comparing number of records in original metadata with extracted height and width lists

print(len(metadata_table))
print(len(width_list))
print(len(height_list))

# Note that extracted lists are shorter than full metadata table, because we skipped missing values.
## Finding average width (for artworks that include that field)

np.mean(width_list)
## Creating a basic histogram

import matplotlib.pyplot as plt
%matplotlib inline

plt.figure(figsize=(13,5))
plt.hist(width_list)
plt.show()

# This isn't very useful. Note that the x axis (i.e., width values) extends to 8000 cm, 
# meaning everything else is squeezed into one histogram bar.
## Viewing the biggest width values

sorted(width_list)[::-1][:30]
## Let's omit all width values above 1000 cm and break up the plot into 30 bins

plt.figure(figsize=(13,5))

temp_width_list = [item for item in width_list if item<=1000]

plt.hist(temp_width_list, bins=30)

plt.show()

# Getting closer ...
## Omitting values above 200 cm and doubling the number of bins to 60

plt.figure(figsize=(13,5))

temp_width_list = [item for item in width_list if item<200]

plt.hist(temp_width_list, bins=60)

plt.show()
## Plotting two overlaid histograms

plt.figure(figsize=(13,5))

temp_width_list = [item for item in width_list if item<200]
temp_height_list = [item for item in height_list if item<200]

plt.hist(temp_width_list, alpha=0.5, label='Widths', bins=60)
plt.hist(temp_height_list, alpha=0.5, label='Heights', bins=60)

plt.legend(loc='upper right')

plt.show()
## Plotting two overlaid histograms with labels

plt.figure(figsize=(13,7))

temp_width_list = [item for item in width_list if item<200]
temp_height_list = [item for item in height_list if item<200]

plt.hist(temp_width_list, alpha=0.5, label='Widths', bins=60)
plt.hist(temp_height_list, alpha=0.5, label='Heights', bins=60)

plt.legend(loc='upper right')

plt.title('Height and Width Distributions')
plt.xlabel('Centimeters')
plt.ylabel('Number of artworks')

plt.show()<jupyter_output><empty_output><jupyter_text>*Scatter Plots: Height and Width Pairs*<jupyter_code>## Creating a list of [height, width] coordinate pairs for each record with valid height and width values

height_width_pairs = []

for row in metadata_table:
    try:
        height = float(row[23])
        width = float(row[26])
        pair = [height, width]
        height_width_pairs.append(pair)
    except:
        pass

height_width_pairs[:10]           # Viewing first 10 [height, width] pairs
## Creating basic scatter plot

import matplotlib.pyplot as plt
%matplotlib inline

x_list = [item[0] for item in height_width_pairs]  # Creating a list of x values (index 0 in each pair)
y_list = [item[1] for item in height_width_pairs]  # Creating a list of y values (index 1 in each pair)

plt.figure(figsize=(6,6))

plt.scatter(x_list, y_list, c='green', alpha=0.5)

plt.show()
## Narrowing visible plot to x and y values under 1000 cm

x_list = [item[0] for item in height_width_pairs]  # Creating a list of x values (index 0 in each pair)
y_list = [item[1] for item in height_width_pairs]  # Creating a list of x values (index 1 in each pair)

plt.figure(figsize=(6,6))

plt.scatter(x_list, y_list, c='green', alpha=0.5)

plt.ylim(ymin=0, ymax=1000)
plt.xlim(xmin=0, xmax=1000)

plt.show()

# Getting closer, but still a bit indistinct. Let's zoom in further.
## Narrowing visible plot to x and y values under 200 cm and increasing plot size

x_list = [item[0] for item in height_width_pairs]  # Creating a list of x values (index 0 in each pair)
y_list = [item[1] for item in height_width_pairs]  # Creating a list of x values (index 1 in each pair)

plt.figure(figsize=(9,9))                          ## <-- Larger plot size

plt.scatter(x_list, y_list, c='green', alpha=0.5)

plt.ylim(ymin=0, ymax=200)                         ## <-- ymax=200
plt.xlim(xmin=0, xmax=200)                         ## <-- xmax=200

plt.show()<jupyter_output><empty_output><jupyter_text>*Pie Chart: Nationality*<jupyter_code>## Creating a list of all items in the 'Nationality' field

nationality_list = []

for row in metadata_table:
    nationality_list.append(row[4])

nationality_list[:10]                  # Viewing first 10 items in nationality_list
## Viewing a few more

print(nationality_list[90])
print(nationality_list[8])
print(nationality_list[3329])
print(nationality_list[703])
## Stripping parentheses from the beginning and end of each item in 'nationality_list'

nationality_list_cleaned = [item.replace('() ', '').strip('()') for item in nationality_list]

nationality_list_cleaned[10000:10010]

# Note that some fields include multiple entries, so we're not done. Let's try again:
## Splitting each item at ')' and discarding everything that follows.
# We're also using .replace() to remove empty '()' entries when they appear first in a list of nationalities.
# We're extracting the first nationality listed and discarding the rest, which may distort the data.

nationality_list_cleaned = [item.replace('() ', '').split(')')[0].strip('()') for item in nationality_list]

nationality_list_cleaned[10000:10010]
### Pie chart with manual labels:

## Looping through list of nationalities, keeping a tally of how many times various values appear

american_tally = 0
french_tally = 0
british_tally = 0
missing_tally = 0
other_tally = 0


for item in nationality_list_cleaned:
    if item == 'American':
        american_tally += 1
    elif item == 'French':
        french_tally += 1
    elif item == 'British':
        british_tally += 1
    elif item == '':
        missing_tally += 1
    else:
        other_tally +=1
### Pie chart with manual labels:

import matplotlib.pyplot as plt
%matplotlib inline

plt.figure(figsize=(8,8))

## A list of numbers, each representing the size of a different category
size_list = [american_tally, french_tally, british_tally, missing_tally, other_tally] 
print(size_list)

## A list of labels corresponding in order with the size list above
label_list = ['American', 'French', 'British', 'Missing nationality', 'Other']
print(label_list)

## Colors corresponding in order with the lists above
# List of color names: https://stackoverflow.com/questions/22408237/named-colors-in-matplotlib
color_list = ['darksalmon', 'yellowgreen', 'lightcoral', 'lightskyblue', 'thistle']

# Plot
plt.pie(size_list, labels=label_list, colors=color_list, autopct='%1.1f%%', shadow=True, startangle=100) 

plt.show()
### Pie chart with automatic labels:

## Creating a list of nationalities by how many times they appear in 'nationality_list', sorted in descending order

from operator import itemgetter
import collections

counter = collections.Counter(nationality_list_cleaned)

nationality_count_pairs = sorted(counter.most_common(), key=itemgetter(1,0), reverse=True)

nationality_count_pairs[:10]
## Creating separate, corresponding lists for nationality values and how many times they appear in MoMA's collection

nationality_descending = [item[0] for item in nationality_count_pairs]
count_descending = [item[1] for item in nationality_count_pairs]

print(nationality_descending[:10])
print(count_descending[:10])
### Pie chart with automatic labels:

import matplotlib.pyplot as plt
import numpy as np

plt.figure(figsize=(8,8))

## A list of numbers, each representing the size of a different category
size_list = count_descending
print(size_list)

## A list of labels corresponding in order with the size list above
label_list = nationality_descending
print(label_list)

## Colors corresponding in order with the lists above, repeating
# List of color names: https://stackoverflow.com/questions/22408237/named-colors-in-matplotlib
color_list = ['darksalmon', 'yellowgreen', 'lightcoral', 'lightskyblue', 'thistle']

# Plot
plt.pie(size_list, labels=label_list, colors=color_list, autopct='%1.1f%%', shadow=True, startangle=100)

plt.show()
### Pie chart with automatic labels:

# Hiding labels for small values to make pie chart more readable

import matplotlib.pyplot as plt
import numpy as np

plt.figure(figsize=(9,9))


## A list of numbers, each representing the size of a different category
size_list = count_descending

## A list of labels corresponding in order with the size list above
label_list = nationality_descending[:10] + ['']*(len(nationality_descending)-10)  ## Keeping the first 10 nationality labels  
                                                                                  ## and setting the rest to empty strings
## Colors corresponding in order with the lists above, repeating
# List of color names: https://stackoverflow.com/questions/22408237/named-colors-in-matplotlib
color_list = ['darksalmon', 'yellowgreen', 'lightcoral', 'lightskyblue', 'thistle']

def my_autopct(pct):                                              ## Defining a function we'll point to in plt.pie() that
    return ('%.2f' % pct) if pct > 1.5 else ''                    ## returns '' (empty string) for percentages below 1.5

# Plot
plt.pie(size_list, labels=label_list, colors=color_list, autopct=my_autopct, shadow=True, startangle=100)

plt.show()<jupyter_output><empty_output><jupyter_text>*Bar Graph: Medium*<jupyter_code>## Creating lists of rows that contain the words 'lithograph', 'woodcut', and 'engraving' in the 'Medium' field

lithograph_rows = []
woodcut_rows = []
engraving_rows = []

for row in metadata_table:
    medium = row[9]                     # 'Medium' field located at index 9 in each row            
    if 'lithograph' in medium.lower():
        lithograph_rows.append(row)     
    if 'woodcut' in medium.lower():     # Using .lower() on field to standardize it, and looking for a lowercase substring 
        woodcut_rows.append(row)
    if 'engraving' in medium.lower():
        engraving_rows.append(row)

# Note that these lists of rows overlap slightly. Some items in MoMA's collection may include two or three of the key words.
## Plotting a basic bar graph

import matplotlib.pyplot as plt
import numpy as np

plt.figure(figsize=(10,7))

x_values = [len(lithograph_rows), len(woodcut_rows), len(engraving_rows)]  ## Using the length of each category's 
                                                                           # list of rows to set bar heights in plot
x_pos = range(len(x_values))          # Location of labels along x axis

plt.bar(x_pos, x_values, alpha=0.5)   # Plotting the bar graph

plt.show()
## Plotting bar graph with labels

import matplotlib.pyplot as plt
import numpy as np

plt.figure(figsize=(10,7))

x_values = [len(lithograph_rows), len(woodcut_rows), len(engraving_rows)]  ## Using the length of each category's 
                                                                           # list of rows for bar heights in plot
x_pos = range(len(x_values))          # Location of labels along x axis

# Setting custom labels, aligned with the position of each bar
x_labels = ['Lithographs', 'Woodcuts', 'Engravings']          # Labels for x axis
plt.xticks(x_pos, x_labels)

plt.bar(x_pos, x_values, alpha=0.5)    # Plotting the bar graph

# Setting title and y axis label
plt.title('Number of artworks by medium')
plt.ylabel('Number of artworks')
 
plt.show()<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.10036107008042015, 'fraction_numerical': 0.022074511734777615, 'mean_word_length': 3.900281463610776, 'pattern_counts': {'":': 0, '<': 26, '<?xml version=': 0, '>': 18, 'https://': 3, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 14, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '4', 'dir': 'jupyter-structured-clean-dedup', 'id': '196273', 'license': 'CC0-1.0', 'n_tokens_mistral': 4059, 'n_tokens_neox': 3721, 'n_words': 1277, 'path': 'MoMA_Visualization_Examples.ipynb', 'repo_name': 'pcda17/pcda', 'size': '12186'}