【Python】数据可视化--基于TMDB_5000_Movie数据集

news2025/2/26 6:10:26

一、数据准备

tmdb_5000_movie数据集下载

二、数据预处理

观察数据集合情况

import pandas as pd
import ast
import warnings
warnings.filterwarnings('ignore')
# 加载数据集
df = pd.read_csv('tmdb_5000_movies.csv')
# 查看数据集信息
print(df.info())

 由于原数据集包含的数据信息较多,因此我们可以在每次需要分析的时候提取部分字段进行分析,比如关键字、电影类型、上映时间、生产厂家、预算、收入等等

df = df[['keywords','genres','production_companies','release_date','budget','revenue','vote_average','vote_count']]

观察过滤完的数据集和我们不难发现存在部分字段缺失值,字段类型数据形式不是我们想要的结果,因此我们对数据集进行进一步处理

import ast

# 将genres、production_companies中的字符串转换为列表
df['genres'] = df['genres'].apply(lambda x: ast.literal_eval(x))
df['production_companies'] = df['production_companies'].apply(lambda x: ast.literal_eval(x))

# 处理缺值数据
filtered_df = df[~df['release_date'].isna()]
filtered_df.dropna(inplace=True)

# 提取日期中的年份
filtered_df['year'] = pd.to_datetime(filtered_df['release_date']).dt.year
filtered_df['year'].apply(int)

三、数据可视化分析

注:下面代码需要上面的预处理结果。

一)2000-2016年期间Twentieth Century Fox Film Corporation、Universal Pictures和Paramount Pictures三家影视公司每年制作的电影数量

二)2012-2016年平均评分前十的电影类型

import matplotlib.pyplot as plt
import seaborn as sns

# 提取待处理字段
filtered_df = filtered_df[['year', 'genres', 'vote_average']]

def split_data(df, split_column):
    # 拆分指定的列
    df = df.explode(split_column)
    # 过滤掉指定列值为nan的数据
    df = df[~df[split_column].isna()]
    # 提取出指定列的名称
    df.loc[:, split_column] = df[split_column].apply(lambda x: x['name'])
    return df

# 拆分genres
filtered_df = split_data(filtered_df, 'genres')
filtered_df.rename(columns={'genres':'genre'}, inplace=True)

# 筛选2012-2016年的电影
filtered_df = filtered_df[(2012 <= filtered_df['year']) & (filtered_df['year'] <= 2016)]
# 计算各电影类型平均评分和
grouped_df = filtered_df.groupby('genre')['vote_average'].mean().reset_index(name='vote_average')
grouped_df = grouped_df.sort_values(by='vote_average', ascending=False)
grouped_df = grouped_df.head(10)

# 生成可视化图表
plt.figure(figsize=(10, 8))
sns.barplot(x=list(grouped_df['genre']),
            y=list(round(grouped_df['vote_average'],2)),
            width=0.6)
plt.ylim(0,8)
plt.title('2012-2016年平均评分前十的电影类型')
plt.xlabel('类型')
plt.ylabel('平均评分')
plt.tight_layout()
plt.legend(['平均评分'])

# 在柱子上方显示每个柱子的值
for index, value in enumerate(list(round(grouped_df['vote_average'],2))):
    plt.text(index, value + 0.08, str(value), ha='center')

plt.show()

运行结果:

三)2016年的总利润中,各电影类型所占的比例

import random

# 提取待处理字段
filtered_df = filtered_df[['year', 'genres','budget', 'revenue']]

# 处理budget、revenue
filtered_df.reset_index(inplace=True)
total = filtered_df['genres'].str.len()
total = total.apply(lambda x: 1 if x == 0 else x)
filtered_df['budget'] = filtered_df['budget'] / total
filtered_df['revenue'] = filtered_df['revenue'] / total

def split_data(df, split_column):
    # 拆分指定的列
    df = df.explode(split_column)
    # 过滤掉指定列值为nan的数据
    df = df[~df[split_column].isna()]
    # 提取出指定列的名称
    df.loc[:, split_column] = df[split_column].apply(lambda x: x['name'])
    return df

# 拆分genres
filtered_df = split_data(filtered_df, 'genres')
filtered_df.rename(columns={'genres':'genre'}, inplace=True)

# 筛选2016年的电影
filtered_df = filtered_df[filtered_df['year'] == 2016]
# 添加利润列
filtered_df['profit'] = filtered_df['revenue'] - filtered_df['budget']
# 过滤利润小于0的
filtered_df = filtered_df[0 <= filtered_df['profit']]
# 计算各电影类型平均利润和
grouped_df = filtered_df.groupby( 'genre')['profit'].sum().reset_index(name='profit')

# 计算各电影类型所占比例
total_scale = grouped_df['profit'].sum()
# 将scale除以整列总和并乘以100,得到每行的比例
grouped_df['scale'] = (grouped_df['profit'] / total_scale) * 100
# 将scale小于1的行的genre设置为"Other"
grouped_df.loc[grouped_df['scale'] < 1, 'genre'] = "Other"
# 计算"Other"行的"profit"和"scale"的总和
other_profit_sum = grouped_df.loc[grouped_df['genre'] == "Other", 'profit'].sum()
other_scale_sum = grouped_df.loc[grouped_df['genre'] == "Other", 'scale'].sum()
grouped_df.loc[grouped_df['genre'] == "Other", ['profit', 'scale']] = [other_profit_sum, other_scale_sum]
grouped_df = grouped_df.sort_values(by='genre')
# print(grouped_df)
# 生成随机颜色
def generate_random_colors(num_colors):
    colors = []
    for _ in range(num_colors):
        # 生成随机的 RGB 值
        r = random.random()
        g = random.random()
        b = random.random()
        colors.append((r, g, b))
    return colors

# 生成可视化图表
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
plt.rcParams['font.size'] = '13'

x = list(grouped_df['genre'])
y = list(round(grouped_df['scale'],2))

plt.figure(figsize=(14, 8))
plt.style.use('ggplot')
bars = plt.barh(x, y, height=0.6, color=generate_random_colors(len(x))[::-1])
plt.xlabel('收入占比', fontsize=14)
plt.ylabel('电影类型', fontsize=14)
plt.tight_layout()

for i, bar in enumerate(bars):
    plt.text(bar.get_width() + 0.2, bar.get_y() + bar.get_height() / 2, f'{y[i]:.1f}%', ha='left',
             va='center', color='green')

plt.title('2016年的总利润中,各电影类型所占的比例', fontsize=18, x=0.5, y=1.05)
plt.show()

运行结果:

四)比较2000-2017年期间Universal Pictures和Paramount Pictures两家影视公司制作各类型电影的数量。

# 提取待处理字段
filtered_df = filtered_df[['year', 'production_companies', 'genres']]
# 筛选2000-2017年的电影
filtered_df = filtered_df[(filtered_df['year'] >= 2000) & (filtered_df['year'] <= 2017)]

def split_data(df, split_column):
    # 拆分指定的列
    df = df.explode(split_column)
    # 过滤掉指定列值为nan的数据
    df = df[~df[split_column].isna()]
    # 提取出指定列的名称
    df.loc[:, split_column] = df[split_column].apply(lambda x: x['name'])
    return df

# 拆分production_companies
filtered_df = split_data(filtered_df, 'production_companies')
filtered_df.rename(columns={'production_companies':'company'}, inplace=True)
filtered_df = filtered_df[(filtered_df['company'] == 'Universal Pictures') | (filtered_df['company'] == 'Paramount Pictures') ]
# 拆分genres
filtered_df = split_data(filtered_df, 'genres')
filtered_df.rename(columns={'genres':'genre'}, inplace=True)

# 根据公司和类型对数据进行分组,并计算每个组的数量
grouped_df = filtered_df.groupby(['company', 'genre']).size().reset_index(name='count')
# print(grouped_df)

# 使用pivot_table函数处理数据
processed_df = pd.pivot_table(grouped_df, values='count', index='genre', columns='company', fill_value=0)
processed_df = processed_df.sort_values(by='genre', ascending=False)
# print(processed_df)

# 生成可视化结果
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
plt.rcParams['font.size'] = '13'

# 设置图形大小和风格
plt.figure(figsize=(12, 8))
plt.style.use('seaborn-muted')

# 数据直接提取
genres = list(processed_df.index)
universal = list(processed_df['Universal Pictures'])
paramount = list(processed_df['Paramount Pictures'])

# 绘制两家公司的数量对比图
plt.barh(np.arange(len(genres)), universal, height=0.3, label='Universal Pictures')
plt.barh(np.arange(len(genres)) + 0.3, paramount, height=0.3, label='Paramount Pictures')

plt.yticks(np.arange(len(genres)) + 0.15, genres, fontsize=12)
plt.legend()
plt.grid(axis='y')

# 添加数据标签
for i, value in enumerate(universal):
    plt.text(value + 0.15, i, str(value), ha='left', va='center', fontsize=10)
for i, value in enumerate(paramount):
    plt.text(value + 0.15, i + 0.3, str(value), ha='left', va='center', fontsize=10)

# 设置标题和坐标轴标签
plt.title('2000-2017年期间Universal Pictures和Paramount Pictures两家影视公司制作各类型电影的数量', fontsize=16)
plt.xlabel('电影数量')
plt.ylabel('电影类型')
plt.tight_layout()
plt.show()

运行结果:

五)比较2010-2016年期间Universal Pictures和Paramount Pictures两家影视公司制作各类型电影的平均利润

# 提取待处理字段
filtered_df = filtered_df[['year', 'production_companies', 'genres', 'revenue', 'budget']]
# 筛选2010-2016年的电影
filtered_df = filtered_df[(filtered_df['year'] >= 2010) & (filtered_df['year'] <= 2016)]

def split_data(df, split_column):
    # 拆分指定的列
    df = df.explode(split_column)
    # 过滤掉指定列值为nan的数据
    df = df[~df[split_column].isna()]
    # 提取出指定列的名称
    df.loc[:, split_column] = df[split_column].apply(lambda x: x['name'])
    return df

# 拆分production_companies
filtered_df = split_data(filtered_df, 'production_companies')
filtered_df.rename(columns={'production_companies':'company'}, inplace=True)
filtered_df = filtered_df[(filtered_df['company'] == 'Universal Pictures') | (filtered_df['company'] == 'Paramount Pictures') ]

# 处理budget、revenue
filtered_df.reset_index(inplace=True)
total = filtered_df['genres'].str.len()
total = total.apply(lambda x: 1 if x == 0 else x)
filtered_df['budget'] = filtered_df['budget'] / total
filtered_df['revenue'] = filtered_df['revenue'] / total

# 拆分genres
filtered_df = split_data(filtered_df, 'genres')
filtered_df.rename(columns={'genres':'genre'}, inplace=True)

# 添加利润列
filtered_df['profit'] = filtered_df['revenue'] - filtered_df['budget']
# 过滤利润小于0的
filtered_df = filtered_df[0 <= filtered_df['profit']]

# 根据公司和类型对数据进行分组,并计算每个组的数量
grouped_df = filtered_df.groupby(['company', 'genre'])['profit'].mean().reset_index(name='average_profit')
# print(grouped_df)

# 使用pivot_table函数处理数据
processed_df = pd.pivot_table(grouped_df, values='average_profit', index='genre', columns='company', fill_value=0)
processed_df = processed_df.sort_values(by='genre', ascending=False)
# print(processed_df)

# 提取Universal Pictures和Paramount Pictures的数据
genres = list(processed_df.index)
universal = list(round(processed_df['Universal Pictures'],2))
paramount = list(round(processed_df['Paramount Pictures'],2))

# 绘制平均利润图
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
plt.rcParams['font.size'] = '13'
plt.figure(figsize=(12, 8))
plt.plot(genres, universal, alpha=0.5, label='Universal Pictures', color='#fa51cf')
plt.bar(genres, paramount, alpha=0.5, label='Paramount Pictures', color='#acaaf1')

plt.title('2010-2016年期间Universal Pictures和Paramount Pictures制作各类型电影的平均利润')
plt.xlabel('类型')
plt.ylabel('平均利润')
plt.legend()
plt.xticks(rotation=45)
plt.show()

运行结果:

六)比较2012-2016年期间Universal和Paramount每年制作各类型电影的数量

from pyecharts import options as opts
from pyecharts.charts import Bar, Timeline

# 提取待处理字段
filtered_df = filtered_df[['year', 'production_companies', 'genres']]
# 筛选2012-2016年的电影
filtered_df = filtered_df[(filtered_df['year'] >= 2012) & (filtered_df['year'] <= 2016)]

def split_data(df, split_column):
    # 拆分指定的列
    df = df.explode(split_column)
    # 过滤掉指定列值为nan的数据
    df = df[~df[split_column].isna()]
    # 提取出指定列的名称
    df.loc[:, split_column] = df[split_column].apply(lambda x: x['name'])
    return df

# 拆分production_companies
filtered_df = split_data(filtered_df, 'production_companies')
filtered_df.rename(columns={'production_companies':'company'}, inplace=True)
filtered_df = filtered_df[(filtered_df['company'] == 'Universal Pictures') | (filtered_df['company'] == 'Paramount Pictures') ]

# 拆分genres
filtered_df = split_data(filtered_df, 'genres')
filtered_df.rename(columns={'genres':'genre'}, inplace=True)

# 根据公司和类型对数据进行分组,并计算每个组的数量
grouped_df = filtered_df.groupby(['year', 'company', 'genre']).size().reset_index(name='count')
# print(grouped_df)

# 获取所有年份、公司和类型的组合
all_years = grouped_df['release_year'].unique()
all_companies = grouped_df['company'].unique()


# 创建空的DataFrame用于存储合并后的数据
merged_df = pd.DataFrame(columns=['release_year', 'company', 'genre', 'count'])

# 遍历所有年份、公司和类型的组合
for year in all_years:
    all_genres = grouped_df[grouped_df['release_year'] == year]['genre'].unique()
    all_genres.sort()
    for company in all_companies:
        for genre in all_genres:
            # 检查是否存在对应的记录
            condition = (grouped_df['release_year'] == year) & (grouped_df['company'] == company) & (
                    grouped_df['genre'] == genre)
            if len(grouped_df[condition]) > 0:
                count = grouped_df[condition]['count'].values[0]
            else:
                count = 0
            # 添加记录到合并后的DataFrame
            merged_df = pd.concat([merged_df, pd.DataFrame(
                {'release_year': [year], 'company': [company], 'genre': [genre], 'count': [count]})],
                                  ignore_index=True)

# print(merged_df)

# 创建时间轮番图
timeline = Timeline(
    init_opts=opts.InitOpts(
        width='1200px',
        height='600px',
        animation_opts=opts.AnimationOpts(
            animation_delay=1000, # 动画延时
            animation_easing='elasticOut'
        )
    )
)

# 遍历每个年份
for year in all_years:
    # 提取当前年份的数据
    universal_data = merged_df[(merged_df['release_year'] == year) & (merged_df['company'] == 'Universal Pictures')]
    paramount_data = merged_df[(merged_df['release_year'] == year) & (merged_df['company'] == 'Paramount Pictures')]

    # 创建柱状图
    bar = (
        Bar(init_opts=opts.InitOpts(height='500px'))
        .add_xaxis(universal_data['genre'].tolist())
        .add_yaxis('Universal Pictures',
                   universal_data['count'].tolist(),
                   gap=0,
                   itemstyle_opts=opts.ItemStyleOpts(
                       color='#FF4D4F')
                   )
        .add_yaxis('Paramount Pictures',
                   paramount_data['count'].tolist(),
                   gap=0,
                   itemstyle_opts=opts.ItemStyleOpts(
                       color='#1890FF')
                   )
        .set_global_opts(
            title_opts=opts.TitleOpts(
                title=f'{int(year)}年 Universal和Paramount制作各类型电影的数量',
                pos_left='center',
            ),
            xaxis_opts=opts.AxisOpts(
                axislabel_opts=opts.LabelOpts(
                    rotate=30,
                    font_size=12,
                )
            ),
            yaxis_opts=opts.AxisOpts(
                name='数量',
                max_=max(universal_data['count'].max(), paramount_data['count'].max())+1,
                axislabel_opts=opts.LabelOpts(
                    font_size=12
                )
            ),
            # visualmap_opts=opts.VisualMapOpts(
            #     min_=0,
            #     max_=8,
            #     is_show=False
            # ),
            # datazoom_opts=[
            #     opts.DataZoomOpts(
            #         range_start = 0,
            #         range_end = 100
            #     )
            # ],
            legend_opts=opts.LegendOpts(
                pos_right='10%',
                pos_top='12%',
                orient='vertical'
            ),
            tooltip_opts=opts.TooltipOpts(
                trigger='item',
                axis_pointer_type='cross'
            )
        )
    )

    # 将柱状图添加到时间轮番图中
    timeline.add(bar, f'{int(year)}年')

# 调整时间轴位置
timeline.add_schema(
    orient="vertical",  # 垂直展示
    is_auto_play=True,
    play_interval=2000,  # 播放时间间隔,毫秒
    pos_right="2%",
    pos_top="50",
    height="500",  # 组件高度
    width="70",
    label_opts=opts.LabelOpts(
        is_show=True,
        color="black",
        position='left'
    ),
)

# 渲染并保存时间轮番图
timeline.render('时间轮番图.html')

运行结果:(时间轮番图)

七)2000-2016年期间产量最高五家电影公司出产电影的平均评分

from pyecharts import options as opts
from pyecharts.charts import Line, Bar
from pyecharts.globals import ThemeType
from pyecharts.render import make_snapshot
from snapshot_selenium import snapshot

# 提取待处理字段
filtered_df = filtered_df[['year', 'production_companies', 'vote_average']]
# 2000-2016年期间产量最高五家电影公司出产电影的平均评分
filtered_df = filtered_df[(2000 <= filtered_df['year']) & (filtered_df['year'] <= 2016)]

def split_data(df, split_column):
    # 拆分指定的列
    df = df.explode(split_column)
    # 过滤掉指定列值为nan的数据
    df = df[~df[split_column].isna()]
    # 提取出指定列的名称
    df.loc[:, split_column] = df[split_column].apply(lambda x: x['name'])
    return df

# 拆分production_companies
filtered_df = split_data(filtered_df, 'production_companies')
filtered_df.rename(columns={'production_companies':'company'}, inplace=True)

grouped_df = filtered_df.groupby('company').agg(
    count=('company', 'size'),
    vote_average=('vote_average', 'mean')).reset_index()

grouped_df = grouped_df.sort_values(by='count', ascending=False)
grouped_df = grouped_df.head(5)
grouped_df = grouped_df.sort_values(by='company')
print(grouped_df)

x_index = grouped_df['company'].tolist()
y_value1 = round(grouped_df['vote_average'],2).tolist()
y_value2 = grouped_df['count'].tolist()

bar = (
    Bar(
        init_opts=opts.InitOpts(
            width="800px",
            height="400px",
            theme=ThemeType.LIGHT
        )
    )
    .add_xaxis(xaxis_data=x_index)
    .add_yaxis(
        series_name="平均评分",
        y_axis=y_value1,
        category_gap="50%",
        label_opts=opts.LabelOpts(is_show=False)
    )

    .extend_axis(  # 第二坐标轴
        yaxis=opts.AxisOpts(
            name="产出数量",
            type_="value",
            min_=100,
            max_=250,
            interval=20,
            axislabel_opts=opts.LabelOpts(formatter="{value}部")  # 设置坐标轴格式
        )
    )
    .set_global_opts(
        title_opts=opts.TitleOpts(
            title="2000-2016年期间产量最高五家电影公司出产电影的平均评分",
        ),
        tooltip_opts=opts.TooltipOpts(
            is_show=True, trigger="axis", axis_pointer_type="cross"
        ),
        legend_opts=opts.LegendOpts(
            pos_right='15%',
            pos_top='5%',
        ),
        xaxis_opts=opts.AxisOpts(
            type_="category",
            axispointer_opts=opts.AxisPointerOpts(is_show=True, type_="shadow"),
            axislabel_opts=opts.LabelOpts(rotate=25)
        ),
        yaxis_opts=opts.AxisOpts(
            name="平均评分",
            type_="value",
            min_=5,
            max_=7,
            interval=0.2,
            axislabel_opts=opts.LabelOpts(formatter="{value} 分"),  # 设置坐标轴格式
            axistick_opts=opts.AxisTickOpts(is_show=True),
            splitline_opts=opts.SplitLineOpts(is_show=True),
        ),
    )
)

line = (
    Line()
    .add_xaxis(xaxis_data=x_index)
    .add_yaxis(
        series_name="产出数量",
        yaxis_index=1,
        y_axis=y_value2,
        itemstyle_opts=opts.ItemStyleOpts(color="red"),
        label_opts=opts.LabelOpts(is_show=False),
        z=2  # 使折线图显示在柱状图上面
    )
)
title = '2000-2016年期间产量最高五家电影公司出产电影的平均评分'
make_snapshot(snapshot, bar.overlap(line).render(title+'.html'), title+'.png')

八)2016年的总票房收入中,各电影公司所占的比例

from pyecharts import options as opts
from pyecharts.charts import Line, Bar
from pyecharts.globals import ThemeType
from pyecharts.render import make_snapshot
from snapshot_selenium import snapshot

# 提取待处理字段
filtered_df = filtered_df[['year', 'production_companies', 'revenue']]
# 2016年的总票房收入中,各电影公司所占的比例
filtered_df = filtered_df[(filtered_df['year'] == 2016)]
# 处理收入列
total = filtered_df['production_companies'].str.len()
total = total.apply(lambda x: 1 if x == 0 else x)
# print(total)
filtered_df['revenue'] = filtered_df['revenue'] / total

def split_data(df, split_column):
    # 拆分指定的列
    df = df.explode(split_column)
    # 过滤掉指定列值为nan的数据
    df = df[~df[split_column].isna()]
    # 提取出指定列的名称
    df.loc[:, split_column] = df[split_column].apply(lambda x: x['name'])
    return df


# 拆分production_companies
filtered_df = split_data(filtered_df, 'production_companies')
filtered_df.rename(columns={'production_companies': 'company'}, inplace=True)
# print(filtered_df.head(10).to_string())

# 按公司分组
grouped_df = filtered_df.groupby( 'company')['revenue'].sum().reset_index(name='revenue')
# 计算总票房收入
total_revenue = grouped_df['revenue'].sum()
# 添加比例列
grouped_df['scale'] = (grouped_df['revenue'] / total_revenue) * 100
grouped_df['revenue'] = round(grouped_df['revenue']/10000,2)

# 将scale小于2的行的company设置为"Other"
grouped_df.loc[grouped_df['scale'] < 1, 'company'] = "Other"
# 计算"Other"行的"revenue"和"scale"的总和
other_revenue_sum = grouped_df.loc[grouped_df['company'] == "Other", 'revenue'].sum()
other_scale_sum = grouped_df.loc[grouped_df['company'] == "Other", 'scale'].sum()
grouped_df.loc[grouped_df['company'] == "Other", ['revenue', 'scale']] = [other_revenue_sum, other_scale_sum]
# 删除重复行
grouped_df = grouped_df.drop_duplicates()
# 按比例排序
grouped_df = grouped_df.sort_values(by='company')
# print(grouped_df.head(20).to_string())

# 提取绘图数据集合
x_index = grouped_df['company'].tolist()
y_value1 = grouped_df['revenue'].tolist()
y_value2 = grouped_df['scale'].tolist()

bar = (
    Bar(
        init_opts=opts.InitOpts(
            width="1200px",
            height="500px",
            theme=ThemeType.LIGHT
        )
    )
    .add_xaxis(xaxis_data=x_index)
    .add_yaxis(
        series_name="票房收入",
        y_axis=y_value1,
        category_gap="50%",
        label_opts=opts.LabelOpts(is_show=False)
    )

    .extend_axis(  # 第二坐标轴
        yaxis=opts.AxisOpts(
            name="所占比例",
            type_="value",
            min_=1,
            max_=5,
            # interval=200,
            axislabel_opts=opts.LabelOpts(formatter="{value} %")  # 设置坐标轴格式
        )
    )
    .set_global_opts(
        title_opts=opts.TitleOpts(
            title="2016年的总票房收入中,各电影公司所占的比例",
        ),
        tooltip_opts=opts.TooltipOpts(
            is_show=True, trigger="axis", axis_pointer_type="cross"
        ),
        legend_opts=opts.LegendOpts(
            pos_right='15%',
            pos_top='5%',
        ),
        xaxis_opts=opts.AxisOpts(
            type_="category",
            axispointer_opts=opts.AxisPointerOpts(is_show=True, type_="shadow"),
            axislabel_opts=opts.LabelOpts(rotate=25)
        ),
        yaxis_opts=opts.AxisOpts(
            name="票房收入",
            type_="value",
            # min_=5,
            # max_=7,
            # interval=0.2,
            # axislabel_opts=opts.LabelOpts(formatter="{value} $"),  # 设置坐标轴格式
            axistick_opts=opts.AxisTickOpts(is_show=True),
            splitline_opts=opts.SplitLineOpts(is_show=True),
        ),
    )
)

line = (
    Line()
    .add_xaxis(xaxis_data=x_index)
    .add_yaxis(
        series_name="所占比例",
        yaxis_index=1,
        y_axis=y_value2,
        itemstyle_opts=opts.ItemStyleOpts(color="red"),
        label_opts=opts.LabelOpts(is_show=False),
        z=2  # 使折线图显示在柱状图上面
    )
)
title = '2016年的总票房收入中,各电影公司所占的比例'
make_snapshot(snapshot, bar.overlap(line).render(title+'.html'), title+'.png')

运行结果:

九)对比2011-2016年期间改编电影和原创电影每年平均票房收入

import json
from pyecharts import options as opts
from pyecharts.charts import Line, Bar
from pyecharts.globals import ThemeType
from pyecharts.render import make_snapshot
from snapshot_selenium import snapshot

# 提取待处理字段
filtered_df = filtered_df[['year', 'keywords', 'revenue']]
# 对比2011-2016年期间改编电影和原创电影每年平均票房收入,电影的其中一个keywords为“based on novel”,则它为改编电影,否则为原创电影
filtered_df = filtered_df[(2011 <= filtered_df['year']) & (filtered_df['year'] <= 2016)]


# 定义函数来判断电影是否为改编电影
def is_adapted_movie(keywords_json):
    try:
        keywords = json.loads(keywords_json.replace("'", '"'))
        return any(keyword['name'] == 'based on novel' for keyword in keywords)
    except json.JSONDecodeError:
        return False


# 为数据集添加一列以标记改编电影
filtered_df['is_adapted'] = filtered_df['keywords'].apply(is_adapted_movie)
# print(filtered_df['is_adapted'])

# print(filtered_df.groupby(['year', 'is_adapted'])['revenue'].mean().head(10).to_string())
grouped_df = filtered_df.groupby(['year', 'is_adapted'])['revenue'].mean().unstack()
print(grouped_df.head(10).to_string())
# 准备数据用于绘图
x_index = grouped_df.index.tolist()
y_value1 = grouped_df[True].tolist()
y_value2 = grouped_df[False].tolist()

bar = (
    Bar(
        init_opts=opts.InitOpts(
            width="800px",
            height="400px",
            theme=ThemeType.LIGHT
        )
    )
    .add_xaxis(xaxis_data=x_index)
    .add_yaxis(
        'Adapted',
        y_axis=y_value1,
        gap=0,
        label_opts=opts.LabelOpts(is_show=False),
        itemstyle_opts=opts.ItemStyleOpts(
            color='#1890FF')
    )
    .add_yaxis(
        'Original',
        y_axis=y_value2,
        gap=0,
        label_opts=opts.LabelOpts(is_show=False),
        itemstyle_opts=opts.ItemStyleOpts(
            color='#FF4D4F')
    )
    .set_global_opts(
        title_opts=opts.TitleOpts(
            title="对比2011-2016年期间改编电影和原创电影每年平均票房收入",
        ),
        tooltip_opts=opts.TooltipOpts(
            is_show=True, trigger="axis", axis_pointer_type="cross"
        ),
        legend_opts=opts.LegendOpts(
            pos_right='15%',
            pos_top='5%',
        ),
        xaxis_opts=opts.AxisOpts(
            type_="category",
            axispointer_opts=opts.AxisPointerOpts(is_show=True, type_="shadow"),
            axislabel_opts=opts.LabelOpts(rotate=25)
        ),
        yaxis_opts=opts.AxisOpts(
            name="平均收入",
            type_="value",
            axistick_opts=opts.AxisTickOpts(is_show=True),
            splitline_opts=opts.SplitLineOpts(is_show=True),
        ),
    )
)
title = '对比2011-2016年期间改编电影和原创电影每年平均票房收入'
make_snapshot(snapshot, bar.render(title + '.html'), title + '.png')

运行结果:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1383010.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

DM数据库安装注意事项

数据库安装注意事项 一、安装前 一些参数需要在数据库创建实例前找用户确认。 参数名参数掩码参数值备注数据页大小PAGE_SIZE32数据文件使用的页大小(缺省使用8K&#xff0c;建议默认&#xff1a;32)&#xff0c;可以为 4K、8K、16K 或 32K 之一&#xff0c;选择的页大小越大…

UCB Data100:数据科学的原理和技巧:第十六章到第十八章

十六、交叉验证和正则化 Cross Validation and Regularization 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 学习成果 认识到需要验证和测试集来预览模型在未知数据上的表现 应用交叉验证来选择模型超参数 了解 L1 和 L2 正则化的概念基础 在特征工程讲座结束时…

QT上位机开发(进度条操作)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 进度条是一个比较常见的控件。如果某个操作需要很长的时间才能完成&#xff0c;那么这个时候最好有一个进度条提示&#xff0c;这样比较容易平复一…

鸿蒙(HarmonyOS)应用开发指南

1. 概述 1.1 简介 鸿蒙&#xff08;即 HarmonyOS &#xff0c;开发代号 Ark&#xff0c;正式名称为华为终端鸿蒙智能设备操作系统软件&#xff09;是华为公司自 2012 年以来开发的一款可支持鸿蒙原生应用和兼容 AOSP 应用的分布式操作系统。该系统利用“分布式”技术将手机、电…

centos 7 上如何安装chrome 和chrome-driver

centos 7 上如何安装chrome 和chrome-driver 查找自己的服务器是什么系统 cat /etc/os-release这里以centos linux 7为例 下载google-chrome安装包 wget https://dl.google.com/linux/direct/google-chrome-stable_current_x86_64.rpm安装chrome sudo yum localinstall go…

C++ 输入用户名和密码 防止注入攻击

1、问题解释&#xff1a;注入攻击 &#xff0c;无密码直接登录数据库 可视化展示 1.1、当你的数据库为&#xff1a;其中包含三个字段id user 以及md5密码 1.2、在使用C堆数据库信息进行访问的时候&#xff0c;使用多条语句进行查询 string sql "select id from t_user…

阿里云最新优惠券领取方法及优惠活动汇总

随着互联网的飞速发展&#xff0c;云服务已经成为企业和个人使用的重要基础设施。阿里云作为全球领先的云服务提供商&#xff0c;一直致力于为用户提供优质的云服务。为了回馈用户&#xff0c;阿里云会定期推出各种优惠券和优惠活动&#xff0c;本文将为大家介绍阿里云最新优惠…

Unity中的异步编程【7】——在一个异步方法里播放了animation动画,取消任务时,如何停止动画播放

用一个异步方法来播放一个动画&#xff0c;正常情况是&#xff1a;动画播放结束时&#xff0c;异步方法宣告结束。那如果我提前取消这个异步任务&#xff0c;那在这个异步方法里面&#xff0c;我要怎么停止播放呢&#xff1f;&#xff01; 一、播放animation动画的异步实现 1…

医疗器械网络安全风险评定CVSS打分

为了完成医疗器械软件的网络安全风险评定相关文档&#xff0c;需要进行CVSS评分&#xff0c;这个评分对于第一次做的人来说感觉还是有些迷惑的&#xff0c;查了一些资料&#xff0c;留作参考。 CVSS 指的是 Common Vulnerability Scoring System&#xff0c;即通用漏洞评分系统…

七、HorizontalPodAutoscaler(HPA)

目录 一、HPA概述&#xff1a; 二、HPA工作机制&#xff1a; 三、HPA流程: 四、HPA API对象: 五、示例&#xff1a; 1、基于CPU的HPA 2、常见问题&#xff1a; 3、基于内存的HPA 一、HPA概述&#xff1a; Horizontal Pod Autoscaler&#xff0c;中文就是水平自动伸缩可…

JUC02同步和锁

同步&锁 相关笔记&#xff1a;www.zgtsky.top 临界区 临界资源&#xff1a;一次仅允许一个进程使用的资源成为临界资源 临界区&#xff1a;访问临界资源的代码块 竞态条件&#xff1a;多个线程在临界区内执行&#xff0c;由于代码的执行序列不同而导致结果无法预测&am…

mysql清空并重置自动递增初始值

需求&#xff1a;当上新项目时&#xff0c;测试环境数据库导出来的表id字段一般都有很大的初始递增值了&#xff0c;需要重置一下 先上代码&#xff1a; -- 查看当前自动递增值 SHOW CREATE TABLE table_name; -- 重建自动递增索引&#xff08;可选&#xff09; ALTER TABLE t…

初学者的基本 Python 面试问题和答案

文章目录 专栏导读1、什么是Python&#xff1f;列出 Python 在技术领域的一些流行应用。2、在目前场景下使用Python语言作为工具有什么好处&#xff1f;3、Python是编译型语言还是解释型语言&#xff1f;4、Python 中的“#”符号有什么作用&#xff1f;5、可变数据类型和不可变…

【深度学习:Micro-Models】用于标记图像和视频的微模型简介

【深度学习&#xff1a;Micro-Models】用于标记图像和视频的微模型简介 微模型&#xff1a;起源故事微模型到底是什么&#xff1f;更详细地解释微观模型&#xff1a;一维标签蝙蝠侠效率 在计算机视觉项目中使用微模型的额外好处面向数据的编程 在本文中&#xff0c;我们将介绍 …

qt5.14.2配置opencv4.5.5

使用环境&#xff1a;windows&#xff0c;opencv4.5.5&#xff0c;qt5.14.2&#xff0c;msvc编译器 这里的opencv文件是已经编译好了&#xff0c;在qt工程中配置就可使用&#xff0c;编译器得是msvc才行&#xff0c;MinGW不管用。 资源地址&#xff1a;https://download.csdn.…

【年终总结】回首2023的精彩,迈向2024的未来

文章目录 一、历历在目&#xff0c;回首成长之路&#x1f3c3;‍1、坚持输出&#xff0c;分享所学2、积土成山&#xff0c;突破万粉3、不断精进&#xff0c;向外涉足 二、雅俗共赏&#xff0c;阅历百般美好&#x1f3bb;1、音乐之声&#xff0c;声声入耳2、书海遨游&#xff0c…

10.9.2 std::function 代替函数指针

std::function是一个模板类&#xff0c;基本可作为函数指针的代替品&#xff0c;具备更多功能&#xff0c;特别是与函数对象及bind配合使用。使用std::function时&#xff0c;需要添加头文件 #include <functional> 1.定义函数指针 18行&#xff0c;定义了一个函数指针类…

ssm基于java的智能训练管理平台论文

摘 要 互联网发展至今&#xff0c;无论是其理论还是技术都已经成熟&#xff0c;而且它广泛参与在社会中的方方面面。它让信息都可以通过网络传播&#xff0c;搭配信息管理工具可以很好地为人们提供服务。针对信息管理混乱&#xff0c;出错率高&#xff0c;信息安全性差&#x…

【位运算】【二分查找】【C++算法】100160价值和小于等于 K 的最大数字

作者推荐 【动态规划】【字符串】扰乱字符串 本文涉及的基础知识点 二分查找算法合集 位运算 LeetCode100160. 价值和小于等于 K 的最大数字 给你一个整数 k 和一个整数 x 。 令 s 为整数 num 的下标从1 开始的二进制表示。我们说一个整数 num 的 价值 是满足 i % x 0 且…

[书生·浦语大模型实战营]——XTuner 大模型单卡低成本微调

1.Finetune简介 在未经过微调的pretrained LLM中&#xff0c;模型只会尽量去拟合你的输入&#xff0c;也就是说模型并没有意识到你在提问&#xff0c;因此需要微调来修正。 1.1常用的微调模式 LLM的下游应用中,增量预训练和指令跟随是经常会用到的两种的微调模式。 增量预训练…