{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Inspired and based on:\n",
"- https://shiny.rstudio.com/gallery/movie-explorer.html\n",
"- https://demo.bokeh.org/movies\n",
"- https://github.com/bokeh/bokeh/tree/master/examples/app/movies"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"tags": [
"parameters"
]
},
"outputs": [],
"source": [
"flex_subtitle = \"built using jupyter-flex\"\n",
"flex_external_link = \"https://github.com/danielfrg/jupyter-flex/blob/master/examples/movie-explorer.ipynb\"\n",
"\n",
"flex_title = \"Movie explorer\"\n",
"flex_show_source = True"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"tags": [
"meta"
]
},
"outputs": [],
"source": [
"import sqlite3 as sql\n",
"from os.path import dirname, join\n",
"\n",
"import numpy as np\n",
"import pandas.io.sql as psql\n",
"\n",
"import plotly.graph_objects as go\n",
"from bokeh.sampledata.movies_data import movie_path\n",
"\n",
"import ipywidgets as widgets\n",
"from IPython.display import display"
]
},
{
"cell_type": "markdown",
"metadata": {
"tags": [
"sidebar"
]
},
"source": [
"# Sidebar"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"axis_map = {\n",
" \"Tomato Meter\": \"Meter\",\n",
" \"Numeric Rating\": \"numericRating\",\n",
" \"Number of Reviews\": \"Reviews\",\n",
" \"Box Office (dollars)\": \"BoxOffice\",\n",
" \"Length (minutes)\": \"Runtime\",\n",
" \"Year\": \"Year\",\n",
"}"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"genres = \"\"\"\n",
"All\n",
"Action\n",
"Adventure\n",
"Animation\n",
"Biography\n",
"Comedy\n",
"Crime\n",
"Documentary\n",
"Drama\n",
"Family\n",
"Fantasy\n",
"History\n",
"Horror\n",
"Music\n",
"Musical\n",
"Mystery\n",
"Romance\n",
"Sci-Fi\n",
"Short\n",
"Sport\n",
"Thriller\n",
"War\n",
"Western\n",
"\"\"\""
]
},
{
"cell_type": "markdown",
"metadata": {
"tags": [
"size=8"
]
},
"source": [
"### Filter"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"tags": [
"body"
]
},
"outputs": [],
"source": [
"components = []\n",
"\n",
"reviews_label = widgets.HTML(value=\"Minimum number of reviews on Rotten Tomatoes:\")\n",
"reviews = widgets.IntSlider(value=80, min=10, max=300, step=1)\n",
"components.extend([reviews_label, reviews])\n",
"\n",
"released_year_label = widgets.HTML(value=\"Year released:\")\n",
"released_year = widgets.IntRangeSlider(value=[1970, 2014], min=1940, max=2014, step=1)\n",
"components.extend([released_year_label, released_year])\n",
"\n",
"oscars_label = widgets.HTML(value=\"Minimum number of Oscar wins (all categories):\")\n",
"oscars = widgets.IntSlider(value=0, min=0, max=4, step=1)\n",
"components.extend([oscars_label, oscars])\n",
"\n",
"boxoffice_label = widgets.HTML(value=\"Dollars at Box Office (millions):\")\n",
"boxoffice = widgets.IntSlider(value=0, min=0, max=800, step=1)\n",
"components.extend([boxoffice_label, boxoffice])\n",
"\n",
"genre_label = widgets.HTML(value=\"Genre (a movie can have multiple genres):\")\n",
"genre = widgets.Dropdown(options=genres.split(\"\\n\"), value=\"All\")\n",
"components.extend([genre_label, genre])\n",
"\n",
"director_label = widgets.HTML(value=\"Director name contains (e.g., Miyazaki):\")\n",
"director = widgets.Text()\n",
"components.extend([director_label, director])\n",
"\n",
"cast_label = widgets.HTML(value=\"Cast names contains (e.g. Tom Hanks):\")\n",
"cast = widgets.Text()\n",
"components.extend([cast_label, cast])\n",
"\n",
"all_widgets = widgets.VBox(components)\n",
"all_widgets"
]
},
{
"cell_type": "markdown",
"metadata": {
"tags": [
"size=4"
]
},
"source": [
"### Variables"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"tags": [
"body"
]
},
"outputs": [],
"source": [
"components = []\n",
"\n",
"x_axis_label = widgets.HTML(value=\"X-axis variable:\")\n",
"x_axis = widgets.Dropdown(options=list(axis_map.items()), value=\"Meter\")\n",
"components.extend([x_axis_label, x_axis])\n",
"\n",
"y_axis_label = widgets.HTML(value=\"Y-axis variable:\")\n",
"y_axis = widgets.Dropdown(options=list(axis_map.items()), value=\"Reviews\")\n",
"components.extend([y_axis_label, y_axis])\n",
"\n",
"note = \"Note: The Tomato Meter is the proportion of positive reviews (as judged by the Rotten Tomatoes staff), and the Numeric rating is a normalized 1-10 score of those reviews which have star ratings (for example, 3 out of 4 stars).\"\n",
"note_label = widgets.HTML(value=note)\n",
"components.append(note_label)\n",
"\n",
"all_widgets = widgets.VBox(components)\n",
"all_widgets"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Movies"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Movie explorer"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"tags": [
"source"
]
},
"outputs": [],
"source": [
"conn = sql.connect(movie_path)\n",
"\n",
"query = \"\"\"\n",
"SELECT omdb.ID,\n",
" imdbID,\n",
" Title,\n",
" Year,\n",
" omdb.Rating as mpaaRating,\n",
" Runtime,\n",
" Genre,\n",
" Released,\n",
" Director,\n",
" Writer,\n",
" omdb.Cast,\n",
" imdbRating,\n",
" imdbVotes,\n",
" Language,\n",
" Country,\n",
" Oscars,\n",
" tomatoes.Rating as numericRating,\n",
" Meter,\n",
" Reviews,\n",
" Fresh,\n",
" Rotten,\n",
" userMeter,\n",
" userRating,\n",
" userReviews,\n",
" BoxOffice,\n",
" Production\n",
"FROM omdb, tomatoes\n",
"WHERE omdb.ID = tomatoes.ID AND Reviews >= 10\n",
"\"\"\"\n",
"\n",
"movies = psql.read_sql(query, conn)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"tags": [
"source"
]
},
"outputs": [],
"source": [
"movies[\"color\"] = np.where(movies[\"Oscars\"] > 0, \"orange\", \"grey\")\n",
"movies[\"alpha\"] = np.where(movies[\"Oscars\"] > 0, 0.9, 0.25)\n",
"movies.fillna(0, inplace=True) # just replace missing values with zero\n",
"movies[\"revenue\"] = movies.BoxOffice.apply(lambda x: '{:,d}'.format(int(x)))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"tags": [
"source"
]
},
"outputs": [],
"source": [
"fig = go.FigureWidget()\n",
"plot = go.Scatter(x=[], y=[], mode=\"markers\", text=[], hoverinfo=\"text\", marker=dict(color=[], opacity=[], size=7))\n",
"fig.add_trace(plot)\n",
"\n",
"margin = go.layout.Margin(l=20, r=20, b=20, t=30)\n",
"fig = fig.update_layout(margin=margin)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"tags": [
"source"
]
},
"outputs": [],
"source": [
"def select_movies():\n",
" selected = movies[\n",
" (movies.Reviews >= reviews.value) &\n",
" (movies.BoxOffice >= (boxoffice.value * 1e6)) &\n",
" (movies.Year >= released_year.value[0]) &\n",
" (movies.Year <= released_year.value[1]) &\n",
" (movies.Oscars >= oscars.value)\n",
" ]\n",
" if (genre.value != \"All\"):\n",
" selected = selected[selected.Genre.str.contains(genre.value)==True]\n",
" if (director.value != \"\"):\n",
" selected = selected[selected.Director.str.contains(director.value)==True]\n",
" if (cast.value != \"\"):\n",
" selected = selected[selected.Cast.str.contains(cast.value)==True]\n",
" return selected\n",
"\n",
"\n",
"def on_value_change(change):\n",
" df = select_movies()\n",
" x_name = x_axis.value\n",
" y_name = y_axis.value\n",
"\n",
" fig.data[0]['x'] = df[x_name]\n",
" fig.data[0]['y'] = df[y_name]\n",
" fig.data[0]['marker']['color'] = df[\"color\"]\n",
" fig.data[0]['marker']['opacity'] = df[\"alpha\"]\n",
" fig.data[0]['text'] = df[\"Title\"] + \"
\" + df[\"Year\"].astype(str) + \"
\" + df[\"BoxOffice\"].astype(str)\n",
" \n",
" fig.update_xaxes(title_text=x_axis.label)\n",
" fig.update_yaxes(title_text=y_axis.label)\n",
" fig.update_layout(title=\"%d movies selected\" % len(df))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"tags": [
"source"
]
},
"outputs": [],
"source": [
"controls = [reviews, boxoffice, released_year, oscars, genre, director, cast, x_axis, y_axis]\n",
"for control in controls:\n",
" control.observe(on_value_change, names=\"value\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"tags": [
"body"
]
},
"outputs": [],
"source": [
"on_value_change(None)\n",
"fig"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"celltoolbar": "Tags",
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"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.10"
}
},
"nbformat": 4,
"nbformat_minor": 4
}