1
$\begingroup$

I'm doing the "video games sales" project downloaded from kaggle, the data is like this: data.head()

and I want to know on each Platform, which are the most three popular Genres? but I don't know how to visualize it, I use pandas to filter the data, here is the code: filter the data

so how could I use pandas(or seaborn,etc.) to finish this target? I'm appreciate for your answers...

$\endgroup$

2 Answers 2

0
$\begingroup$

How to keep the top 3

In a convenient DataFrame

You can use the method nlargest to keep the best 3 of each index.

df.groupby(["Genre","Platform"]).size()
        .reset_index(level=1)
        .groupby("Platform")[0]
        .nlargest(3).to_frame("Game_count)

Step by step explanation

  • I assumed that, by "popularity", you meaan the game count. We first group byGenre and Platform, and we take the size of each group, as you did but with both the columns swapped.

    step1 = df.groupby(["Genre", "Platform"]).size()
    

Step 1

  • We reset the index to drop one level, so we have indices set to Genre.

    step2 = step1.reset_index(level=1)
    

Step 2

  • We group back to Platform and keep the 3 largest values

    step3 = step2.groupby("Platform")[0].nlargest(3) # 0 is the default name of the size column.
    

Step 3

  • We make it a DataFrame, assigning an appropriate name.

    top3_df = step3.toframe("Game_count")
    

Result

Resulting dataframe


How to visualize

Since we have many platforms and many genres (even considering the Top3 only), we cannot reasonably represent all the informations in a single plot. But we can have multiple plots.

  • Let's first reset the index, to flatten our dataframe. We will also list our genres in an alphabetic order.

    import seaborn as sns
    top3_df.reset_index(inplace=True)
    genres = top3_df.Genre.sort_values().unique()
    
  • We have to assign each genre to a specific color, so each keeps its color in all plots. We will use a seaborn color_palette and link it to each genre thanks to a dictionary.

    genres_palette = dict(zip(genres, sns.color_palette("Set3", len(genre))
    
  • Now, let's design a function to plot each platform in a separate axe. We also pass it our palette dictionary :

    def plot_platform(dataframe, name, ax):
        # We also sort the dataframe in decreasing order of Game count
        sns.barplot(x="Genre", y="Game_count", 
                data=dataframe.sort_values("Game_count", ascending=False),
                palette=genre_palette, ax=ax)
        ax.set_title(f"By platform: {name}")
    
  • Finally plotting...

    fig = plt.figure(figsize=(20,32), constrained_layout=True) # Quite big to fit all data comfortably
    gridspecs = fig.add_gridspecs((len(platforms)+3) // 3, 4) # A grid of width 4
    
    # One call to our custom plot function by platform:
    for index, platform in enumerate(platforms):
       # Next cell in our grid. We let the right-most column for the legend
       ax = fig.add_subplot(gridspecs[index // 3, index % 3])
       plot_platform(top3_df[top3_df.Platform==platform], platform, ax)
    
    # Now adding the legends
    from matplotlib.patches import Patch
    # The entire fourth column is for the legend
    fig_legend_ax = fig.add_subplot(gridspecs[0:,-1])
    fig_legend_ax.axis("off")
    fig_legend_ax.legend(
            # One patch per genre, with its color and name.
            handles=[Patch(facevolor=col, label=genre) for genre, col in genre_palette.items()], 
            # Let's make it quite big and with no visible frame
            loc="center left", frameon=False, prop={"size": 25})
    
     plt.show()
    

Result

Please note that the following preview is largely zoomed-out.

Global visualization

Of course, you can customize it with other color palette, sizes and layouts.

$\endgroup$
0
$\begingroup$

So your question is how to plot the top 3 game genres for each game platform (console). You are definitely on the right track in using the groupby method.

It is a bit long winded, but this would definitely do the job:

c = df.groupby(["Platform", "Genre"]).size().reset_index()
c.columns = ["Platform", "Genre", "Frequency"]

for p in df["Platform"].unique():
    """
    This line will take a subset of the c dataframe such that it only contains
    entries for a particular platform.
    The .sort_values() method will then arrange the frequency in descending order.
    The .head(n) will then take the top n entries and therefore, the top three genres
    for a particular platform.
    """
    df_ = c[c["Platform"] == p].sort_values("Frequency")
    sns.barplot(x = "Platform", y = "Frequency", hue = "Genre", data = df_)
    plt.show()

Here, you can edit the code so that for each platform, each graph appears on a separate axis.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.