{ "cells": [ { "cell_type": "code", "execution_count": 1, "id": "61304542", "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "try:\n", " import IPython\n", "except:\n", " !pip install IPython\n", " import IPython \n", "from IPython.core.display import HTML\n", "from IPython.display import display, IFrame, HTML\n", "\n", "# add stylesheet for notebook\n", "HTML(\"\"\"\"\"\")" ] }, { "cell_type": "markdown", "id": "c09fa7b0", "metadata": {}, "source": [ "# Linked Art Visualisation of John Ruskin \n", "\n", "\n", "This notebook is concerned with a visualisation of artworks represented in Linked Art abd demonstrates how a timeline visualisation of John Ruskin's artworks can be created using:\n", "- collections data transformed to Linked Art\n", "- a script to transform the Linked Art JSON-LD representation to a JSON input file\n", "- the KnightLab visualisation service\n", "\n", "The JSON-LD files for John Ruskin's artworks were created with other notebooks:\n", "- [Ruskin Transformation notebook](01-06-Transform-John-Ruskin.ipynb)\n", "- [Ruskin Reconciliation notebook](02-01-Reconcile-John-Ruskin-Place-Names.ipynb)\n", "\n", "KnightLab has a visualisation service that allows you to create an interactive timeline visualisation very quickly and easily. The timeline visualisation can take as input as Google speadsheet or a local CSV file. This notebook described first how to create the visualisation with a Google spreadsheet, and later how to use a local CSV file.\n", "\n", "From [http://timeline.knightlab.com/](http://timeline.knightlab.com/):\n", "
\n", "TimelineJS is an open-source tool that enables anyone to build visually rich, interactive timelines. Beginners can create a timeline using nothing more than a Google spreadsheet, like the one we used for the Timeline above. Experts can use their JSON skills to create custom installations, while keeping TimelineJS's core functionality.\n", "
\n", "\n", "The method for creating a visualisation is a simple one:\n", "- use a script to transform Linked Art JSON-LD files to a CSV format as defined by KnightLab\n", " - [Google spreadsheet template for a timeline](https://docs.google.com/spreadsheets/d/1pHBvXN7nmGkiG8uQSUB82eNlnL8xHu6kydzH_-eguHQ/copy)\n", "\n", "The method then differs depending on use of a Google spreadsheet vs local CSV file.\n", "\n", "#### Further Reading\n", "- [KnightLab visualisation service](https://knightlab.northwestern.edu/projects/)\n", "- [Google docs](https://doc.google.com)\n", "\n", "Detailed requirements and instructions are available at:\n", "- [http://timeline.knightlab.com/](http://timeline.knightlab.com/)\n" ] }, { "cell_type": "markdown", "id": "e5c72a9a", "metadata": {}, "source": [ "## Read in Linked Art files and transform to CSV timeline template" ] }, { "cell_type": "code", "execution_count": 8, "id": "25c066fb", "metadata": {}, "outputs": [], "source": [ "ruskin_la_files = \"./data/ruskin/output/json/\"" ] }, { "cell_type": "code", "execution_count": 9, "id": "bd985534", "metadata": {}, "outputs": [], "source": [ "import os\n", "try:\n", " import json\n", "except:\n", " !pip install json\n", " import json \n", "\n", "import csv\n", "\n", " \n", "sources = {}\n", "sources[\"https://www.nga.gov/collection/\"] = {\"name\":\"National Gallery of Art\",\"colour\": \"#E8A798\"}\n", "sources[\"https://clevelandart.org/art/\"] = {\"name\":\"Cleveland Museum of Art\", \"colour\":\"#EDD59E\"}\n", "sources[\"https://www.philamuseum.org/collection/object/\"] = {\"name\":\"Philadelphia Museum of Art\",\"colour\":\"#6B5876\"}\n", "sources[\"https://www.tate.org.uk/art/artworks/\"] = {\"name\":\"Tate Museum\",\"colour\":\"#A09998\"}\n", "sources[\"https://www.harvardartmuseums.org/collections/object/\"] = {\"name\":\"Harvard Art Museum\",\"colour\":\"#00758F\"}\n", "sources[\"ashmolean\"] = {\"name\":\"Ashmolean Museum\",\"colour\":\"#3f83e8\"}\n", "sources[\"rijk\"] = {\"name\":\"Rijksmuseum\",\"colour\":\"#94b7c3\"}\n", "\n", " \n", "json_all = {}\n", "\n", "# get list of Linked Art JSON-LD files for John Ruskin, created with 01-06-Transform-John-Ruskin.ipynb and 02-01-Reconcile-John-Ruskin-Place-Names.ipynb\n", "file_list=os.listdir(r\"./data/ruskin/output/json/\")\n", " \n", " \n", "for file in file_list:\n", " with open( ruskin_la_files + file) as json_file:\n", " json_text = json.load(json_file)\n", " json_all.update({file : json_text})\n", " \n", "my_dict = []\n", "\n", "title_rows = [\n", " {\n", " \"Year\": \"\",\n", " \"Month\" : \"\",\n", " \"Day\" : \"\",\n", " \"Time\" : \"\",\n", " \"End Year\": \"\",\n", " \"End Month\" : \"\",\n", " \"End Day\" : \"\",\n", " \"End Time\" : \"\",\n", " \"Display Date\": \"\",\n", " \"Headline\" : \"John Ruskin\" ,\n", " \"Text\": \"

This timeline visualisation shows artworks created by John Ruskin.

It demonstrates how the Linked Art data model can be used to transform, reconcile and visualise collections data for artworks.

See https://linked.art for more information.

\",\n", " \"Media\": \"https://upload.wikimedia.org/wikipedia/commons/0/0a/John_Ruskin_1863.jpg\",\n", " \"Media Credit\": \"Wikipedia\",\n", " \"Media Caption\": \"John Ruskin\",\n", " \"Media Thumbnail\" : \"\",\n", " \"Type\": \"title\",\n", " \"Group\" :\"\",\n", " \"Background\": \"\" },\n", " \n", " {\n", " \"Year\": \"1819\",\n", " \"Month\" : 2,\n", " \"Day\" : 8,\n", " \"Time\" : \"\",\n", " \"End Year\": \"1900\",\n", " \"End Month\" : 1,\n", " \"End Day\" : 20,\n", " \"End Time\" : \"\",\n", " \"Display Date\": \"\",\n", " \"Headline\" : \"John Ruskin's lifetime\" ,\n", " \"Text\": \"\",\n", " \"Media\": \"https://en.wikipedia.org/wiki/John_Ruskin#/media/File:John_Ruskin_1863.jpg\",\n", " \"Media Credit\": \"Wikipedia\",\n", " \"Media Caption\": \"John Ruskin\",\n", " \"Media Thumbnail\" : \"\",\n", " \"Type\": \"era\",\n", " \"Group\" :\"\",\n", " \"Background\": \"\"},\n", " \n", "]\n", "\n", "my_dict = title_rows\n", "\n", "for file in json_all:\n", " artwork = json_all[file]\n", " \n", " id = artwork[\"id\"]\n", " \n", " if \"_label\" not in artwork:\n", " continue\n", " \n", " if \"produced_by\" not in artwork:\n", " continue\n", " \n", " if \"begin_of_the_begin\" not in artwork[\"produced_by\"][\"timespan\"]:\n", " continue\n", " \n", " if artwork[\"produced_by\"][\"timespan\"][\"begin_of_the_begin\"] == 1819:\n", " continue\n", " \n", " credit = \"\"\n", " for source in list(sources.keys()):\n", " if source in id:\n", " credit = sources[source][\"name\"]\n", " bgcolour = sources[source][\"colour\"]\n", " \n", " text = \"\"\n", " imageurl = \"\"\n", " homepage = \"\"\n", " \n", " if \"referred_to_by\" in artwork and len(artwork[\"referred_to_by\"]) > 0 and \"content\" in artwork[\"referred_to_by\"][0]: \n", " text = artwork[\"referred_to_by\"][0][\"content\"]\n", " \n", " \n", " if artwork[\"subject_of\"][0][\"classified_as\"][1][\"id\"] == \"http://vocab.getty.edu/aat/300266277\":\n", " homepage = artwork[\"subject_of\"][0][\"id\"]\n", " text = text + \"

Artwork homepage\"\n", " \n", " if artwork[\"representation\"][0][\"id\"] != \"\":\n", " imageurl = artwork[\"representation\"][0][\"id\"]\n", " \n", " if \"begin_of_the_begin\" in artwork[\"produced_by\"][\"timespan\"]:\n", " begin = artwork[\"produced_by\"][\"timespan\"][\"begin_of_the_begin\"]\n", " try:\n", " begin = int(begin)\n", " except:\n", " begin = \"\"\n", " \n", " if \"end_of_the_end\" in artwork[\"produced_by\"][\"timespan\"]:\n", " end = artwork[\"produced_by\"][\"timespan\"][\"end_of_the_end\"]\n", " try:\n", " end = int(end)\n", " except:\n", " end = \"\"\n", " \n", " if abs(begin-end)>10:\n", " continue\n", " if imageurl == \"\" or \"placeholder\" in imageurl:\n", " continue\n", "\n", " row = {\n", " \"Year\": begin,\n", " \"Month\" : 1,\n", " \"Day\" : 1,\n", " \"Time\" : \"\",\n", " \"End Year\": end,\n", " \"End Month\" : 12,\n", " \"End Day\" : 31,\n", " \"End Time\" : \"\",\n", " \"Display Date\": artwork[\"produced_by\"][\"timespan\"][\"_label\"],\n", " \"Headline\" : artwork[\"_label\"] ,\n", " \"Text\": text,\n", " \"Media\": imageurl,\n", " \"Media Credit\": credit,\n", " \"Media Caption\": \"\",\n", " \"Media Thumbnail\" : imageurl,\n", " \"Type\": \"title\",\n", " \"Group\" :\"\",\n", " \"Background\": bgcolour \n", " }\n", " my_dict.append(row)\n", "\n", "with open('./data/ruskin/output/csv/ruskin_vis.csv', 'w') as f: \n", " w = csv.DictWriter(f, my_dict[0].keys())\n", " w.writeheader()\n", " for row in my_dict:\n", " w.writerow(row)\n", " " ] }, { "cell_type": "markdown", "id": "48d67c2e", "metadata": {}, "source": [ "## Result - Timeline CSV File\n", "\n", "The result of the script transformation is a CSV timeline file, as shown below:" ] }, { "cell_type": "code", "execution_count": 10, "id": "6fc07206", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
YearMonthDayTimeEnd YearEnd MonthEnd DayEnd TimeDisplay DateHeadlineTextMediaMedia CreditMedia CaptionMedia ThumbnailTypeGroupBackground
0NaNNaNNaNNaNNaNNaNNaNNaNNaNJohn Ruskin<p>This timeline visualisation shows artworks ...https://upload.wikimedia.org/wikipedia/commons...WikipediaJohn RuskinNaNtitleNaNNaN
11819.02.08.0NaN1900.01.020.0NaNNaNJohn Ruskin's lifetimeNaNhttps://en.wikipedia.org/wiki/John_Ruskin#/med...WikipediaJohn RuskinNaNeraNaNNaN
21870.01.01.0NaN1870.012.031.0NaNbefore 1870Engraving of Ruskin's Drawing of the Petal Vau...<br/><br/><a target='_new' href='https://colle...https://collections.ashmolean.org/media/ashmol...Ashmolean MuseumNaNhttps://collections.ashmolean.org/media/ashmol...titleNaN#3f83e8
31869.01.01.0NaN1869.012.031.0NaNearly November 1869Enlarged Study of a Prawn's Rostrum<br/><br/><a target='_new' href='https://colle...https://collections.ashmolean.org/media/ashmol...Ashmolean MuseumNaNhttps://collections.ashmolean.org/media/ashmol...titleNaN#3f83e8
41852.01.01.0NaN1852.012.031.0NaN1852(?)Study of a Venetian CapitalFine Arts Department, Harvard University, Camb...https://nrs.harvard.edu/urn-3:HUAM:VRS48802_dynmcHarvard Art MuseumNaNhttps://nrs.harvard.edu/urn-3:HUAM:VRS48802_dynmctitleNaN#00758F
\n", "
" ], "text/plain": [ " Year Month Day Time End Year End Month End Day End Time \\\n", "0 NaN NaN NaN NaN NaN NaN NaN NaN \n", "1 1819.0 2.0 8.0 NaN 1900.0 1.0 20.0 NaN \n", "2 1870.0 1.0 1.0 NaN 1870.0 12.0 31.0 NaN \n", "3 1869.0 1.0 1.0 NaN 1869.0 12.0 31.0 NaN \n", "4 1852.0 1.0 1.0 NaN 1852.0 12.0 31.0 NaN \n", "\n", " Display Date Headline \\\n", "0 NaN John Ruskin \n", "1 NaN John Ruskin's lifetime \n", "2 before 1870 Engraving of Ruskin's Drawing of the Petal Vau... \n", "3 early November 1869 Enlarged Study of a Prawn's Rostrum \n", "4 1852(?) Study of a Venetian Capital \n", "\n", " Text \\\n", "0

This timeline visualisation shows artworks ... \n", "1 NaN \n", "2

Timeline visualisation" ], "text/plain": [ "" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "vis = \"https://cdn.knightlab.com/libs/timeline3/latest/embed/index.html?source=1mQjqB9EowQTJY_G7nlDoN71In3fZqjuuqu1olq5OQ2g&font=Default&lang=en&timenav_position=top&initial_zoom=2&height=650\"\n", "\n", "HTML(\"Timeline visualisation\")" ] }, { "cell_type": "code", "execution_count": 6, "id": "c6297fbe", "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", " \n", " " ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "display(IFrame(vis, width='100%', height=700))" ] }, { "cell_type": "markdown", "id": "977a8704", "metadata": {}, "source": [ "## Timeline Using a Local CSV file\n", "\n", "The following HTML code shows how to publish a timeline using a local CSV file" ] }, { "cell_type": "code", "execution_count": 12, "id": "f502bd12", "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", " \n", "\n", " \n", " \n", "\n", "

\n", "\n", " \n", " \n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "%%HTML\n", "\n", " \n", "\n", " \n", " \n", "\n", "
\n", "\n", " \n", " " ] }, { "cell_type": "markdown", "id": "b8d48621", "metadata": {}, "source": [ "## Next Steps\n", "\n", "A number of videos are available that describe the process of creating hte timeline visualisation\n", "\n", "- https://vimeo.com/143407878\n", "- https://www.youtube.com/watch?v=ZUVUjt7jd1c\n", "\n", "A [code notebook](03-04-Visualise-John-Ruskin-Story-Map.ipynb) describes how to use the KnightLab StoryMap visualisation service." ] } ], "metadata": { "finalized": { "timestamp": 1651435190752, "trusted": true }, "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.8" } }, "nbformat": 4, "nbformat_minor": 5 }