利用棒棒糖圖探索Office (US)的IMDB評分

利用棒棒糖圖探索Office (US)的IMDB評分

import numpy as np
import pandas as pd
import matplotlib.colors as mc
import matplotlib.image as image
import matplotlib.pyplot as pltfrom matplotlib.cm import ScalarMappable
from matplotlib.lines import Line2D
from matplotlib.offsetbox import OffsetImage, AnnotationBbox
from mpl_toolkits.axes_grid1.inset_locator import inset_axes
from palettable import cartocolors # 獲得好看的顏色

數據探索

以下數據如果有需要的同學可關注公眾號HsuHeinrich,回復【數據可視化】自動獲取~

df_office = pd.read_csv("https://raw.githubusercontent.com/rfordatascience/tidytuesday/master/data/2020/2020-03-17/office_ratings.csv")
df_office.head()

image-20240129175359876

season:季度

episode:劇集編號

imdb_rating:IMDB評級

total_votes:每個評級使用的投票數

df_office_avg = df_office.sort_values(["season", "episode"])
# 生成episode_id:自增序列
df_office_avg["episode_id"] = np.arange(len(df_office_avg)) + 1
df_office_avg["episode_mod"] =  df_office_avg["episode_id"] + (9 * df_office_avg["season"])
df_office_avg = df_office_avg.assign(avg = df_office_avg.groupby("season")["imdb_rating"].transform("mean"),mid = df_office_avg.groupby("season")["episode_mod"].transform("mean")
)df_office_avg.head()

image-20240129175424360

創建df_lines數據集:以便于繪制表示每個季度評分平均值的水平線,這些線將在每個季度的第一個和最后一個劇集之間延伸,并稍微超過這些點

df_lines = df_office_avg.groupby("season").agg(start_x = ("episode_mod", min),end_x = ("episode_mod", max),y = ("avg", max) # 每個season的avg一樣,用max獲取唯一值
).reset_index()# 在每個方向上稍微延長水平線
df_lines["start_x"] -= 5
df_lines["end_x"] += 5df_lines = pd.melt(df_lines, id_vars=["season", "y"], value_vars=["start_x", "end_x"], var_name="type", value_name="x"
)
df_lines["x_group"] = np.where(df_lines["type"] == "start_x", df_lines["x"] + 0.1, df_lines["x"] - 0.1)
df_lines["x_group"] = np.where((df_lines["type"] == "start_x").values & (df_lines["x"] == np.min(df_lines["x"])).values, df_lines["x_group"] - 0.1, df_lines["x_group"]
)
df_lines["x_group"] = np.where((df_lines["type"] == "end_x").values & (df_lines["x"] == np.max(df_lines["x"])).values, df_lines["x_group"] + 0.1, df_lines["x_group"]
)
df_lines = df_lines.sort_values(["season", "x_group"])
df_lines.head()

image-20240129175446112

繪制棒棒糖圖

圖片logo為the-office,可在網上自行下載,也可以關注公眾號HsuHeinrich,回復【可視化素材】自動獲取~

def adjust_lightness(color, amount=0.5):'''調整顏色亮度:低于 1 的值使其變暗,高于 1 的值使其變亮'''import matplotlib.colors as mcimport colorsystry:c = mc.cnames[color]except:c = colorc = colorsys.rgb_to_hls(*mc.to_rgb(c))return colorsys.hls_to_rgb(c[0], max(0, min(1, amount * c[1])), c[2])
# 定義一些變量# 顏色
GREY82 = "#d1d1d1"
GREY70 = "#B3B3B3"
GREY40 = "#666666"
GREY30 = "#4d4d4d"
BG_WHITE = "#fafaf5"# 季節顏色調整
COLORS = ["#486090", "#D7BFA6", "#6078A8", "#9CCCCC", "#7890A8","#C7B0C1", "#B5C9C9", "#90A8C0", "#A8A890"]
COLORS_DARK = [adjust_lightness(color, 0.8) for color in COLORS]
COLORS_LIGHT = [adjust_lightness(color, 1.2) for color in COLORS]# 三種顏色調整函數
cmap_regular = mc.LinearSegmentedColormap.from_list("regular", COLORS)
cmap_dark = mc.LinearSegmentedColormap.from_list("dark", COLORS_DARK)
cmap_light = mc.LinearSegmentedColormap.from_list("light", COLORS_LIGHT)# 對季節進行縮放
normalize = mc.Normalize(vmin=1, vmax=9)# 圖片存儲
IMAGE = image.imread("pic/the-office.jpg")# 水平線
HLINES = [6.5, 7, 7.5, 8, 8.5, 9, 9.5, 10]
VOTES_MAX = df_office_avg["total_votes"].max()
VOTES_MIN = df_office_avg["total_votes"].min()# 縮放票數,用于棒棒糖的大小
def scale_to_interval(x, low=15, high=150):return ((x - VOTES_MIN) / (VOTES_MAX - VOTES_MIN)) * (high - low) + low
# 初始化布局
fig, ax = plt.subplots(figsize = (15, 10))# 背景顏色
fig.patch.set_facecolor(BG_WHITE)
ax.set_facecolor(BG_WHITE)# 繪制水平參考線,zorder=0位于圖層最下方
for h in HLINES:plt.axhline(h, color=GREY82, zorder=0)# 垂直線段:代表劇集評分與平均評分的偏差
plt.vlines(x="episode_mod", ymin="imdb_rating", ymax="avg",color=cmap_light(normalize(df_office_avg["season"])),data = df_office_avg
)# 水平線:連接平均值的灰線
plt.plot("x", "y", "-", color=GREY40, data=df_lines)# 水平線:每個賽季的平均分 
for season in df_lines["season"].unique():d = df_lines[df_lines["season"] == season]plt.plot("x_group", "y", "", color=cmap_dark(normalize(season)), lw=5, data=d, solid_capstyle="butt")# 點:每集的評分,大小由投票數決定
plt.scatter("episode_mod", "imdb_rating",s = scale_to_interval(df_office_avg["total_votes"]),color=cmap_regular(normalize(df_office_avg["season"])), data=df_office_avg,zorder=3
)# Season標簽
midpoints = df_office_avg["mid"].unique()
for season, mid in enumerate(midpoints):color = cmap_dark(normalize(season + 1))plt.text(mid, 10.12, f" Season {season + 1} ", color=color,weight="bold",ha="center",va="center",fontname="Special Elite",fontsize=11,bbox=dict(facecolor="none", edgecolor=color, linewidth=1,boxstyle="round", pad=0.2))# ------------------------自定義布局------------------------# 隱藏邊框
ax.spines["right"].set_color("none")
ax.spines["top"].set_color("none")
ax.spines["bottom"].set_color("none")
ax.spines["left"].set_color("none")# 自定義y軸
plt.tick_params(axis="y", labelright=True, length=0)
plt.yticks(HLINES, fontname="Roboto", fontsize=11, color=GREY30)
plt.ylim(0.98 * 6.5, 10.2 * 1.02)# 移除x刻度
plt.xticks([], "")# 設置y標簽
plt.ylabel("IMDb Rating", fontname="Roboto", fontsize=14)# 添加著作信息
plt.text(0.5, -0.03, "Visualization by Cédric Scherer  ?  Data by IMDb via data.world  ?  Fanart Logo by ArieS", fontname="Special Elite", fontsize=11, color=GREY70,ha="center", va="center", transform=ax.transAxes # so coordinates are in terms of the axis.
)# 放置圖片logo
ab = AnnotationBbox(OffsetImage(IMAGE, zoom=0.2), (1, 6.75), xycoords="data", box_alignment=(0, 0.5),pad=0, frameon=False
)
ax.add_artist(ab)# ------------------------自定義圖例------------------------# 水平圖例點及其標簽的位置
x_pos = [0.44, 0.48, 0.52, 0.56]
votes = [2000, 4000, 6000, 8000]# 繪制圖例點
plt.scatter(x_pos, [0.065] * 4, s=scale_to_interval(np.array(votes)), color="black",transform=ax.transAxes
)# 添加圖例標簽名
plt.text(0.5, 0.0875, "Votes per Episode", fontname="Roboto", fontsize=10, ha="center", transform=ax.transAxes)# 將圖例放在圖例標記下方
for (xpos, vote) in zip(x_pos, votes):plt.text(xpos, 0.035,  f"{vote}", fontname="Roboto", fontsize=9, ha="center", transform=ax.transAxes)plt.show()

png

參考:The Office Ratings with Python and Matplotlib

共勉~

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/921009.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/921009.shtml
英文地址,請注明出處:http://en.pswp.cn/news/921009.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Zephyr如何注冊設備實例

設備樹 → 編譯期生成 → 運行時訪問 流程圖&#xff1a;Zephyr dev->config 工作流程設備樹 (.dts) ───────────────────────────── anx745139 {compatible "analogix,anx7451";reg <0x39>;reset-gpios <&gpio1 5 …

Spring Boot 日志框架選擇指南:Logback vs Log4j2

在 Spring Boot 應用中&#xff0c;您需要明確選擇一個日志框架 - ??不能同時使用兩種日志實現??。以下是關于 spring-boot-starter-log4j2和 spring-boot-starter-logging的全面比較和選擇建議&#xff1a;核心區別特性spring-boot-starter-log4j2(Log4j2)spring-boot-sta…

Axure科技感可視化原型案例:賦能設計與研發的寶藏資源

在當今數字化浪潮中&#xff0c;數據可視化已成為企業洞察市場、優化運營、快速決策不可或缺的工具。Axure&#xff0c;作為原型設計領域的領航者&#xff0c;憑借其強大的功能和豐富的資源&#xff0c;為數據可視化大屏的設計注入了科技活力與創新元素。本文將深入探討Axure科…

跨境電商賬號風控核心:IP純凈度與瀏覽器指紋的防護策略

對跨境電商從業者而言&#xff0c;賬號突然被封是常見卻令人頭痛的問題。即便嚴格遵守平臺規則、使用代理IP&#xff0c;賬號仍可能因風控策略而受限。這背后&#xff0c;IP純凈度與瀏覽器指紋識別是兩大常被忽視卻至關重要的技術因素。本文將從技術角度解析其原理&#xff0c;…

daily notes[7]

文章目錄perl notereferencesperl note A hash in perl can be initialized with array,for example: my %numbers ("one", 1, "two", 2); print $fruit_color{"one"}; it is wonderful that the hash can be sliced to result in an array …

WPF遷移avalonia之圖像處理(一)

從WPF遷移到avalonia中&#xff0c;對于圖像處理部分&#xff0c;在WPF常用System.Windows.Drawing中圖像處理元素&#xff0c;但是在開發avalonia應用時考慮跨平臺特性&#xff0c;則必須有對應的跨平臺替換方案。主要考慮Avalonia.Media.Imaging.Bitmap和SkiaSharp.SKBitmap …

242. 有效的字母異位詞| 349. 兩個數組的交集

242. 有效的字母異位詞 nums [0]*26 : 這行代碼創建了一個包含26個0的列表&#xff0c;這個列表通常用于計數或者作為某種映射的基礎&#xff0c;比如統計字符串中每個字母出現的次數&#xff08;假設只考慮小寫字母a-z&#xff09;。 ord() Python 中的一個內置函數&#x…

HTML第二課:塊級元素

HTML第二課&#xff1a;塊級元素塊級元素塊級元素 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html lang"zh-CN"> <head><meta http-equiv"Content-…

微論-突觸的作用賦能思考(可能是下一代人工智能架構的啟發式理論)

突觸智能&#xff1a;微觀結構與宏觀智慧的橋梁摘要&#xff1a;傳統人工智能模型&#xff0c;尤其是深度學習&#xff0c;將突觸簡單抽象為一個靜態的權重參數&#xff0c;這極大地簡化了生物計算的復雜性。本文受啟發于生物突觸的微觀功能&#xff0c;提出了一種新的智能架構…

ARM - GPIO 標準庫開發

一、STM32MP157AAA開發板套件介紹1.1 核心板 - 主板如圖所示&#xff1a;主板各部分介紹1.2 IO 拓展板如圖所示&#xff1a;IO拓展板各部分介紹開發板名稱&#xff08;硬件平臺&#xff09;&#xff1a;FS-MP1A主控制器&#xff1a;STM32MP157AAA3 Cortex-A7 * 2 Cortex-M4 -…

橙武低代碼:不僅僅是云SaaS,更是云端開發+本地部署的新范式

版權歸作者所有&#xff0c;轉載請注明出處。 一、低代碼的時代背景 在過去十年里&#xff0c;軟件研發模式經歷了巨大的演變。從傳統的瀑布開發&#xff0c;到敏捷、DevOps&#xff0c;再到如今的低代碼/無代碼平臺&#xff0c;研發效率和交付模式發生了根本性變化。低代碼的…

神經語言學視角:腦科學與NLP深層分析技術的交叉融合

引言&#xff1a;從“統計擬合”到“類人理解”——NLP的下一個范式近年來&#xff0c;以Transformer架構為核心的大型語言模型&#xff08;LLM&#xff09;在自然語言處理&#xff08;NLP&#xff09;領域取得了前所未有的成功 。它們能夠生成流暢的文本、回答復雜的問題&…

Coze源碼分析-工作空間-項目查詢-前端源碼

前言 本文將深入分析Coze Studio項目中用戶登錄后進入工作空間查看和管理項目的前端實現&#xff0c;通過源碼解讀來理解工作空間項目開發功能的架構設計和技術實現。Coze Studio采用了現代化的React TypeScript技術棧&#xff0c;結合微前端架構和模塊化設計&#xff0c;為用…

【系統架構師設計(9)】系統設計:結構化設計與面向對象設計

文章目錄一、核心思想&#xff1a;模塊化與對象化的設計哲學1、結構化設計的核心思想2、面向對象設計的核心思想3、兩種設計方法的本質區別二、結構化設計知識點1、設計階段2、設計原則3、 內聚類型&#xff08;從低到高&#xff09;耦合類型&#xff08;從低到高&#xff09;模…

還在從零開發AI應用?這個項目直接給你500個現成方案!!!

大家好&#xff0c;我是顧北&#xff0c;一名AI應用探索者&#xff0c;也是GitHub開源項目收集者。昨晚又在GitHub上瞎逛...咦&#xff0c;碰到了一個特別有意思的項目。說實話吧&#xff0c;作為一個天天折騰AI工具的人&#xff0c;見過的項目沒有一千也有八百了&#xff0c;但…

react+taro的使用整理

前言&#xff1a; 本文主要整理下我們跨段工具taro的具體使用方法與相關資料。 taro官網&#xff1a; 安裝及使用 | Taro 文檔 安裝&#xff1a; 全局腳手架安裝&#xff1a; npm install -g tarojs/cli 使用腳手架安裝我們的taro項目 taro init myApp 運行到不同小程序教…

從 “容器保姆” 到 “云原生王者”:K8s 全方位指南

目錄 開頭專業總結 一、先搞懂&#xff1a;K8s 到底是什么&#xff1f;能解決什么痛點&#xff1f; 1. K8s 的本質 2. 核心用處&#xff08;解決的痛點&#xff09; 二、K8s 核心知識點&#xff1a;組件與概念&#xff08;標重點&#xff01;&#xff09; &#xff08;一…

03.《交換的底層邏輯:從基礎到應用》

交換基礎 文章目錄交換基礎MAC 地址&#xff1a;設備的 “全球唯一身份證”MAC 地址的基本屬性MAC 地址的三類類型&#xff08;按通信范圍劃分&#xff09;以太幀以太幀的兩個標準格式1. Ethernet_II 格式&#xff08;常用&#xff09;2. IEEE 802.3 格式&#xff08;少用&…

火語言 RPA 界面應用生成:輕量化開發核心優勢

火語言 RPA 界面應用生成功能&#xff0c;主打 “低門檻、快落地”&#xff0c;無需復雜開發環境與專業技術&#xff0c;就能快速實現需求驗證與工具搭建&#xff0c;尤其適配中小團隊與個人&#xff0c;核心優勢如下&#xff1a;?一、1 小時搞定需求驗證&#xff1a;3 步落地…

第三方軟件測試機構【多語言開發(PHP/Java/Python)WEB 應用的安全專業測試流程】

PHP應用測試安全 文件包含漏洞&#xff1a;檢測include/require函數參數未過濾場景&#xff08;如?page../../../etc/passwd&#xff09; 命令注入&#xff1a;檢查system()/exec()函數輸入驗證&#xff08;如| cat /etc/passwd&#xff09; 會話安全&#xff1a;驗證session …