[Визуализация] Визуализация данных Олимпийских игр 2020 года

визуализация данных

«Это 21-й день моего участия в ноябрьском испытании обновлений. Подробную информацию о мероприятии см.:Вызов последнего обновления 2021 г."

На основе полученных данных Олимпийских игр 2020 года в этой статье используются панды и графические диаграммы для создания большого статического экрана визуализации.

Разрабатывать макеты для больших экранов

карта

Рисунок карты относительно прост, и данные в данных напрямую英文名称и奖牌总数Как данные карты, рисование карты может быть реализовано напрямую

По сравнению с отображением теплового значения легенда использует метод трех равных делений, а количество наград более интуитивно понятно.

В большинстве последующих диаграмм используетсяlightЭта тема

import pandas as pd
from pyecharts import options as opts
from pyecharts.charts import Map

df = pd.read_excel("奖牌榜单数据集.xlsx")
data = [[i,j] for i,j in zip(df['英文名称'], df['奖牌总数'])]

charts =  Map(init_opts=opts.InitOpts(theme='light'))
charts.add("奖章总数", data, "world",is_map_symbol_show=False)
charts.set_series_opts(label_opts=opts.LabelOpts(is_show=False))
charts.set_global_opts(title_opts=opts.TitleOpts(title="2020东京奥运会各国金牌分布图"),
                       visualmap_opts=opts.VisualMapOpts(max_=120,is_piecewise=True,split_number=3))
charts.render_notebook()

График с горизонтальным накоплением

Список медалей, показывающий ТОП10, представлен в виде горизонтально расположенного графика, и jpyecharts вызовет его при отрисовке горизонтального изображения.reversal_axis()функции, в это время следует отметить, что данные также должны бытьreverse, поэтому при обработке данных используйте[::-1]преобразовать данныеreverseнемного.

Цвет сопоставляется со слабой курицей автора, соответствующей золотой медали, серебряной медали и бронзовой медали, чтобы найти три цвета, которые можно увидеть.

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

df = pd.read_excel("奖牌榜单数据集.xlsx")
df = df.sort_values(by="奖牌总数",axis=0,ascending=False)
nation = df['名称'].values[:10][::-1].tolist()
gold = df['金牌'].values[:10][::-1].tolist()
silver = df['银牌'].values[:10][::-1].tolist()
copper = df['铜牌'].values[:10][::-1].tolist()

bar = Bar(init_opts=opts.InitOpts(width='1000px',height='600px'))
bar.add_xaxis(nation)
# stack值一样的系列会堆叠在一起
bar.add_yaxis('金牌', gold, stack='stack1',category_gap="50%",color="#e5b751")
bar.add_yaxis('银牌', silver, stack='stack1',category_gap="50%",color="#f1f0ed")
bar.add_yaxis('铜牌', copper, stack='stack1',category_gap="50%",color="#fed71a")
bar.set_series_opts(label_opts=opts.LabelOpts(is_show=False))
bar.set_global_opts(title_opts=opts.TitleOpts(title="东京奥运会奖牌榜TOP10"))
bar.reversal_axis()
bar.render_notebook()

Круговая диаграмма

На круговой диаграмме показаны награды различных конкурсов в Китае,

После того, как часть данных находится в Китае,groupbyПросто возьмите названия статистических элементов и отсортируйте их в порядке убывания.

Последовательность с использованием перечисленияiУстановите положение XY для каждой круговой диаграммы

import pandas as pd
from pyecharts import options as opts
from pyecharts.charts import Pie

df = pd.read_excel("参赛运动员数据集.xlsx")
region_list = ["中国", "中国香港", "中国台北"]
titles = []
pie = Pie(
    init_opts=opts.InitOpts(
        theme='light',
        width='1000px',
        height='800px',
    )
)
for i,r in enumerate(region_list):
    
    sortdata = df[df["国家"]== r].groupby('项目名')['项目名'].count().sort_values(0, ascending=False)
    names = sortdata.index.tolist()
    values = sortdata.values.tolist()
    dataItem = [list(z) for z in zip(names,  values)]
    
    pos_x = '{}%'.format(int(i / 3) * 33 + 18)
    pos_y = '{}%'.format(i % 3 * 28 + 33)
    
    titles.append(dict(text=r+' ',
                       left=pos_x,
                       top=pos_y,
                       textAlign='center',
                       textVerticalAlign='middle',
                       textStyle=dict(color='#603d30',fontSize=12))
                 )
    
    pie.add(
        r,
        dataItem,
        center=[pos_x, pos_y],
        radius=['8%', '12%'],
        label_opts=opts.LabelOpts(is_show=True,formatter='{b}:{d}%')
    )
    


pie.set_global_opts(
    legend_opts=opts.LegendOpts(is_show=False),
    title_opts=titles)
pie.render_notebook()

Лента новостей

учиться уAwesomeTangКак сделать босса

df = pd.read_excel("参赛运动员数据集.xlsx")
y_data = []
counter = 0
position = ['left', 'right']
for idx, row in df[(df['英文缩写']=='CHN') & (df['金牌类型']==1)].iterrows():
    msg = '{bbb|%s}\n{aaa|%s}\n{bbb|%s/%s}' % (row['获奖时间'][:10], row['运动员'], row['项目名'], row['子项目名称'])
    # 单个数据项配置
    l_item = opts.LineItem(
        name=10,
        value=counter,
        symbol='emptyCircle',
        symbol_size=10,
        label_opts=opts.LabelOpts(
            is_show=True, 
            font_size=16,
            position=position[counter%2], 
            formatter=msg,
            rich = {
                'aaa': {
                    'fontSize': 18, 
                    'color': 'red', 
                    'fontWeight':'bold', 
                    'align':position[(counter+1)%2],
                    },
                'bbb': {
                    'fontSize': 15, 
                    'color': '#000', 
                    'align':position[(counter+1)%2]}}
            )
    )
    y_data.append(l_item)
    counter+=1
    
line = Line(
    init_opts=opts.InitOpts(
        theme='light',
        width='1000px',
        height='2000px',
        bg_color='white'
    )
)
line.add_xaxis(
    ['CHN']
)
line.add_yaxis(
    '',
    y_data,
    linestyle_opts={
        'normal': {
            'width': 4,  # 设置线宽
            'color':'red',
            'shadowColor': 'rgba(155, 18, 184, .3)',  # 阴影颜色
            'shadowBlur': 10,  # 阴影大小
            'shadowOffsetY': 10,  # Y轴方向阴影偏移
            'shadowOffsetX': 10,  # x轴方向阴影偏移
        }
    },
    itemstyle_opts={
        'normal': {
            'color':'red',
            'shadowColor': 'rgba(155, 18, 184, .3)',  # 阴影颜色
            'shadowBlur': 10,  # 阴影大小
            'shadowOffsetY': 10,  # Y轴方向阴影偏移
            'shadowOffsetX': 10,  # x轴方向阴影偏移
        }
    },
    tooltip_opts=opts.TooltipOpts(is_show=False)
)

line.set_global_opts(
    xaxis_opts=opts.AxisOpts(is_show=False, type_='category'),
    yaxis_opts=opts.AxisOpts(is_show=False, type_='value', max_=len(y_data)),
    title_opts=opts.TitleOpts(
        title="夺金时刻", pos_left='center', pos_top='2%',
        title_textstyle_opts=opts.TextStyleOpts(color='red', font_size=20)
    ),
    graphic_opts=[
                opts.GraphicGroup(
                            graphic_item=opts.GraphicItem(id_='1',left="center", top="center", z=-1),
                            children=[# tokyo 
                                    opts.GraphicImage(graphic_item=opts.GraphicItem(id_="logo",
                                                                                    left='center',
                                                                                    z=-1),
                                                      graphic_imagestyle_opts=opts.GraphicImageStyleOpts(
                                        image="https://olympics.com/tokyo-2020/en/d3images/emblem/olympics/emblem-tokyo2020.svg",
                                        width=800,
                                        height=1000,
                                        opacity=0.1,)
                                    )
                                ]
                                )
                                ]
)
line.render_notebook()

Макет данных на большом экране

Измените приведенные выше четыре диаграммы на функции и используйте Page, чтобы создать комбинированную диаграмму.

полный код

# https://www.233tw.com/python/59145
import pandas as pd
from pyecharts import options as opts
from pyecharts.charts import *


def map_world()-> Map:
    df = pd.read_excel("奖牌榜单数据集.xlsx")
    data = [[i,j] for i,j in zip(df['英文名称'], df['奖牌总数'])]

    charts =  Map()
    charts.add("奖章总数", data, "world",is_map_symbol_show=False)
    charts.set_series_opts(label_opts=opts.LabelOpts(is_show=False))
    charts.set_global_opts(title_opts=opts.TitleOpts(title="2020东京奥运会各国金牌分布图"),
                           visualmap_opts=opts.VisualMapOpts(max_=120,is_piecewise=True,split_number=3))
    return charts

def bar_medals()->Bar:
    df = pd.read_excel("奖牌榜单数据集.xlsx")
    df = df.sort_values(by="奖牌总数",axis=0,ascending=False)
    nation = df['名称'].values[:10][::-1].tolist()
    gold = df['金牌'].values[:10][::-1].tolist()
    silver = df['银牌'].values[:10][::-1].tolist()
    copper = df['铜牌'].values[:10][::-1].tolist()

    bar = Bar(init_opts=opts.InitOpts(width='1000px',height='600px'))
    bar.add_xaxis(nation)
    # stack值一样的系列会堆叠在一起
    bar.add_yaxis('金牌', gold, stack='stack1',category_gap="50%",color="#e5b751")
    bar.add_yaxis('银牌', silver, stack='stack1',category_gap="50%",color="#f1f0ed")
    bar.add_yaxis('铜牌', copper, stack='stack1',category_gap="50%",color="#fed71a")
    bar.set_series_opts(label_opts=opts.LabelOpts(is_show=False))
    bar.set_global_opts(title_opts=opts.TitleOpts(title="东京奥运会奖牌榜TOP10"))
    bar.reversal_axis()
    return bar

def pie_china()->Pie:
    df = pd.read_excel("参赛运动员数据集.xlsx")
    region_list = ["中国", "中国香港", "中国台北"]
    titles = []
    pie = Pie(
        init_opts=opts.InitOpts(
            theme='light',
            width='1000px',
            height='800px',
        )
    )
    for i,r in enumerate(region_list):

        sortdata = df[df["国家"]== r].groupby('项目名')['项目名'].count().sort_values(0, ascending=False)
        names = sortdata.index.tolist()
        values = sortdata.values.tolist()
        dataItem = [list(z) for z in zip(names,  values)]
        pos_x = '{}%'.format(int(i / 3) * 33 + 18)
        pos_y = '{}%'.format(i % 3 * 28 + 33)
        titles.append(dict(text=r+' ',
                           left=pos_x,
                           top=pos_y,
                           textAlign='center',
                           textVerticalAlign='middle',
                           textStyle=dict(color='#603d30',fontSize=12)))
        pie.add(r,dataItem,center=[pos_x, pos_y],radius=['8%', '12%'],label_opts=opts.LabelOpts(is_show=True,formatter='{b}:{d}%'))
    pie.set_global_opts(legend_opts=opts.LegendOpts(is_show=False),title_opts=titles)
    return pie

def timeline()->Line:
    df = pd.read_excel("参赛运动员数据集.xlsx")
    y_data = []
    counter = 0
    position = ['left', 'right']
    for idx, row in df[(df['英文缩写']=='CHN') & (df['金牌类型']==1)].iterrows():
        msg = '{bbb|%s}\n{aaa|%s}\n{bbb|%s/%s}' % (row['获奖时间'][:10], row['运动员'], row['项目名'], row['子项目名称'])
        # 单个数据项配置
        l_item = opts.LineItem(
            name=10,
            value=counter,
            symbol='emptyCircle',
            symbol_size=10,
            label_opts=opts.LabelOpts(
                is_show=True, 
                font_size=16,
                position=position[counter%2], 
                formatter=msg,
                rich = {
                    'aaa': {
                        'fontSize': 18, 
                        'color': 'red', 
                        'fontWeight':'bold', 
                        'align':position[(counter+1)%2],
                        },
                    'bbb': {
                        'fontSize': 15, 
                        'color': '#000', 
                        'align':position[(counter+1)%2]}}
                )
        )
        y_data.append(l_item)
        counter+=1

    line = Line(
        init_opts=opts.InitOpts(
            theme='light',
            width='1000px',
            height='2000px',
            bg_color='white'
        )
    )
    line.add_xaxis(
        ['CHN']
    )
    line.add_yaxis(
        '',
        y_data,
        linestyle_opts={
            'normal': {
                'width': 4,  # 设置线宽
                'color':'red',
                'shadowColor': 'rgba(155, 18, 184, .3)',  # 阴影颜色
                'shadowBlur': 10,  # 阴影大小
                'shadowOffsetY': 10,  # Y轴方向阴影偏移
                'shadowOffsetX': 10,  # x轴方向阴影偏移
            }
        },
        itemstyle_opts={
            'normal': {
                'color':'red',
                'shadowColor': 'rgba(155, 18, 184, .3)',  # 阴影颜色
                'shadowBlur': 10,  # 阴影大小
                'shadowOffsetY': 10,  # Y轴方向阴影偏移
                'shadowOffsetX': 10,  # x轴方向阴影偏移
            }
        },
        tooltip_opts=opts.TooltipOpts(is_show=False)
    )

    line.set_global_opts(
        xaxis_opts=opts.AxisOpts(is_show=False, type_='category'),
        yaxis_opts=opts.AxisOpts(is_show=False, type_='value', max_=len(y_data)),
        title_opts=opts.TitleOpts(
            title="夺金时刻", pos_left='center', pos_top='2%',
            title_textstyle_opts=opts.TextStyleOpts(color='red', font_size=20)
        ),
        graphic_opts=[
                    opts.GraphicGroup(
                                graphic_item=opts.GraphicItem(id_='1',left="center", top="center", z=-1),
                                children=[# tokyo 
                                        opts.GraphicImage(graphic_item=opts.GraphicItem(id_="logo",
                                                                                        left='center',
                                                                                        z=-1),
                                                          graphic_imagestyle_opts=opts.GraphicImageStyleOpts(
                                            image="https://olympics.com/tokyo-2020/en/d3images/emblem/olympics/emblem-tokyo2020.svg",
                                            width=800,
                                            height=1000,
                                            opacity=0.1,)
                                        )
                                    ]
                                    )
                                    ]
    )
    return line

page = Page(layout=Page.DraggablePageLayout, page_title="2020东京奥运会数据可视化")

# 在页面中添加图表
page.add(
    timeline(),
    map_world(),
    bar_medals(),
    pie_china(),

)
page.load_javascript()
page.render("draghtmlpage.html")

установить макет наPage.DraggablePageLayoutВы можете перетаскивать изображения, чтобы настроить макет.

Откройте сохраненный пользовательский макет html, нажмите после завершения макета.save configСохраните его параметры макетаjsonдокумент.

Наконец, запустите следующую строку кода, вызовите сохраненный файл макета и повторно сгенерируйте html.

a = page.save_resize_html('draghtmlpage.html', cfg_file='chart_config.json', dest='奥运.html')

Эффект:

В изначальной реализации визуализации данных на большом экране еще много недочетов, есть ошибки или несовершенства, прошу критиковать и исправлять! !

Использованная литература:

[1] [Олимпийские игры 2020 в Токио] Визуализация данных~

[2] Научите вас использовать панд для анализа и визуализации данных Олимпийских игр в Токио.

[3] Python делает большой визуальный экран (Олимпийские игры в Токио)