Добавить фильтры в график рассеяния на основе кадра данных панд - PullRequest
1 голос
/ 05 октября 2019

Я притворяюсь, что делаю точечные графики с фильтрами следующего информационного кадра (который представляет за весь сезон игроков, команду и сезон, и подсчитывает количество пропущенных и не оказанных вспомогательных очков, что сделал игрок баскетбольной команды):

player          team_name       season          assisted    notassisted
A. DANRIDGE     NACIONAL        Season_17_18    130         445
A. DANRIDGE     NACIONAL        Season_18_19    132         382
D. ROBINSON     TROUVILLE       Season_18_19    89          286
D. DAVIS        AGUADA          Season_18_19    101         281
E. BATISTA      WELCOME         Season_17_18    148         278
F. MARTINEZ     GOES            Season_18_19    52          259
D. ALVAREZ      AGUADA          Season_17_18    114         246
M. HICKS        H. MACABI       Season_17_18    140         245

По оси x я хочу поместить вспомогательные точки, а по оси y - вспомогательные точки. Но я также хочу фильтровать по сезону, по команде и по игрокам, поэтому, когда я выбираю определенного игрока команды, я могу видеть их очки одним цветом, а другие - серым, или, например, если я хочу выбрать два или болееИгроки, я могу сравнить их между ними (с разными цветами), и что другие точки видны, но серые. Также я хотел бы сравнить игроков двух разных команд и комбинаций фильтров.

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

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

Код выглядит следующим образом:

import plotly.express as px

fig = px.scatter(pointsperplayer, x='assisted', y='notassisted', hover_name='player', 
                 hover_data=['team_name','season'], color='season')
fig.show()

И результирующая диаграмма выглядит следующим образом:

Результирующая диаграмма рассеяния

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

1 Ответ

0 голосов
/ 16 октября 2019

Таким образом, я не смог манипулировать легендой, но я мог добавить фильтры через выпадающие виджеты, которые я нашел здесь . В зависимости от вашей IDE, вам может понадобиться использовать Jupyter, чтобы заставить виджеты работать. Я столкнулся с проблемой невозможности отображения виджетов в VSCode. Ниже у меня есть возможность фильтровать по названию команды, сезону или игроку и сравнивать два варианта в этом фильтре. Я надеюсь, что это может быть расширено для удовлетворения ваших потребностей.

import pandas as pd
import plotly.express as px
import plotly.graph_objects as go
import ipywidgets as ipy
from ipywidgets import Output, VBox, widgets


# First gather the data I need and choose the display colors
playerData = pd.read_csv("playerData.csv")
teamNames = list(playerData['team_name'].unique().tolist());
seasons = list(playerData['season'].unique().tolist());
players = list(playerData['player'].unique().tolist());
color1 = 'red'
color2 = 'blue'
color3 = 'gray'

# This creates the initial figure.
# Note that px.scatter generates multiple scatter plot 'traces'. Each trace contains 
# the data points associated with 1 team/season/player depending on what the property
# of 'color' is set to.
trace1 = px.scatter(playerData, x='assisted', y='notassisted', color='team_name')
fig = go.FigureWidget(trace1)

# Create all our drop down widgets
filterDrop = widgets.Dropdown(
    description='Filter:',
    value='team_name',
    options=['team_name', 'season','player']  
)
teamDrop1 = widgets.Dropdown(
    description='Team Name:',
    value='NACIONAL',
    options=list(playerData['team_name'].unique().tolist())  
)
teamDrop2 = widgets.Dropdown(
    description='Team Name:',
    value='NACIONAL',
    options=list(playerData['team_name'].unique().tolist())  
)
playerDrop1 = widgets.Dropdown(
    description='Player:',
    value='A. DANRIDGE',
    options=list(playerData['player'].unique().tolist())  
)
playerDrop2 = widgets.Dropdown(
    description='Player:',
    value='A. DANRIDGE',
    options=list(playerData['player'].unique().tolist())  
)
seasonDrop1 = widgets.Dropdown(
    description='Season:',
    value='Season_17_18',
    options=list(playerData['season'].unique().tolist())  
)
seasonDrop2 = widgets.Dropdown(
    description='Season:',
    value='Season_17_18',
    options=list(playerData['season'].unique().tolist())  
)

# This will be called when the filter dropdown changes. 
def filterResponse(change):
    # generate the new traces that are filtered by teamname, season, or player
    tempTrace = px.scatter(playerData, x='assisted', y='notassisted', color=filterDrop.value)
    with fig.batch_update():
        # Delete the old traces and add the new traces in one at a time
        fig.data = []
        for tr in tempTrace.data:
            fig.add_scatter(x = tr.x, y = tr.y, hoverlabel = tr.hoverlabel, hovertemplate = tr.hovertemplate, \
                           legendgroup = tr.legendgroup, marker = tr.marker, mode = tr.mode, name = tr.name)
    # Call response so that it will color the markers appropriately
    response(change)

# This is called by all the other drop downs
def response(change):
    # colorList is a list of strings the length of the # of traces 
    if filterDrop.value == 'team_name':
        colorList = [color1 if x == teamDrop1.value else color2 if x == teamDrop2.value else color3 for x in teamNames]
    elif filterDrop.value == 'season':
        colorList = [color1 if x == seasonDrop1.value else color2 if x == seasonDrop2.value else color3 for x in seasons]
    else:
        colorList = [color1 if x == playerDrop1.value else color2 if x == playerDrop2.value else color3 for x in players]
    with fig.batch_update():
        # Color each trace according to our chosen comparison traces
        for i in range(len(colorList)):
            fig.data[i].marker.color = colorList[i]

# These determine what function should be called when a drop down changes
teamDrop1.observe(response, names="value")
seasonDrop1.observe(response, names="value")
playerDrop1.observe(response, names="value")
teamDrop2.observe(response, names="value")
seasonDrop2.observe(response, names="value")
playerDrop2.observe(response, names="value")
filterDrop.observe(filterResponse, names="value")

# HBox and VBox are used to organize the other widgets and figures
container1 = widgets.HBox([filterDrop]) 
container2 = widgets.HBox([teamDrop1, seasonDrop1, playerDrop1])
container3 = widgets.HBox([teamDrop2, seasonDrop2, playerDrop2])
widgets.VBox([container1, container2, container3, fig])

Результат выглядит следующим образом: enter image description here

...