Help needed on px.pie - multiple "values=" possible?

Hi Guys,

I am currently struggling with a single dataframe that i cannot show in a Pie-chart like I want to.

I managed to get a filter running and make a rudimentary table out of it, which shows some data including some marks of people who participated:

What I wanted to achieve:
The Pie-chart should now show all amounts of marks to the Movie and show the ratio of votes in the pie-chart.
Possible Votes:
amount_wertvoll_1, amount_gut_2, amount_okay_3, amount_schlecht_4, amount_grottig_5

Then I tried to create a Pie-chart to show the amount of marks a Movie has received:

I could only get one mark to work, others do not seem to be accepted due to syntax and lead to an error.

pie_chart = px.pie(movie_select,
                   title="film: PLACEHOLDER",
                   values="amount_wertvoll_1",
                   names="movie_name")

st.plotly_chart(pie_chart)

I looked up examples and the docs multiple times, but it looks like they do not cover up my case…
Am I missing something out?
I really appreciate any Help. Thanks in advance

It seems that you are selecting “amount_wertvoll_1” which only includes one value, if you are using px.pie you may want to select a column that has multiple values.

Something like the following:

import streamlit as st
import pandas as pd

import plotly.express as px
d = {'value_options': ['amount_wertvoll_1', 'amount_gut_2','amount_okay_3','amount_schlecht_4','amount_grottig_5'], 'vote_flash_gordon': [3,6,2,1,2]}
df = pd.DataFrame(data=d)


pie_chart = px.pie(df,
                   title="film: PLACEHOLDER",
                   values="vote_flash_gordon",
                   names="value_options")

st.plotly_chart(pie_chart)

Hi, thanks for you reply.

I am not sure if you unterstood what I wanted to do…
I have gained a dataframe (in my case an SQL-Statement) <— No need to change that, works fine

df_from_sql2 = pd.read_sql(
    "SELECT gezeigt_datum, presenter, movie_name, average_vote, genre_name, amount_wertvoll_1, amount_gut_2, amount_okay_3, amount_schlecht_4, amount_grottig_5 FROM movies_shown",
    con=mysql_engine).set_index("gezeigt_datum")

then I created a filter which works dynamically. I dont want Flash Gordon to be shown. This is just an example of the filter/selectbox <— No need to change that, works fine


movie_select = st.selectbox(
    "Folgendes infos eines Films zeigen:",
    options=df_from_sql2["movie_name"].unique()
)

movie_select = df_from_sql2.query(
    "movie_name == @movie_select"
)

st.dataframe(movie_select)

Having one result, I wanted to make a specific pie-chart from it, but the Syntax does not want me to do…
Whenever I add multiple values into values=, I get:

> ValueError: All arguments should have the same length. The length of argument values is 5, whereas the length of previously-processed arguments [‘movie_name’] is 1

The previous code is only an example to demonstrate how a working dataframe would look like. In your case you would take your “movie_select” output and create two columns, one with the column names that would be in the pie chart (indicated as “marks” in the original post) and the other column would be the values of those marks. Then insert the first column in the px.pie names and the second on values.

1 Like

Thanks for your suggestion.
Unfortunately my dataframe looks like it is formatted differently

grafik

The grades are all in the same row, whilst “your” grades are separated with a row…

Your Dataframe looks totally different:

grafik

funny thing is: I was already thinking about reformatting the result, but failed trying to create 5 different dataframes, make a dataframe for each grade separately and then “merge” them afterwards…

any suggestion on this? Will this be the way to go or is there any “elegant” way to reformat it?
The Idea came from https://towardsdatascience.com/turn-your-python-script-into-a-web-app-using-streamlit-and-altair-627c70c56f4?gi=2d229bc9f6a0 which also has separade “grades” (bronze, silver, gold) in every row…
To be honest: I do not have any clue to make this happen…

Update on this:
I managed to reformat this!
I used the pandas.melt - Function
So in my case i did following:

like documented before I filtered the dataframe (optional) into “movie_select”

Then i did following:

movie_select_pie_format = movie_select

movie_select_pie_format = pd.melt(movie_select_pie_format, id_vars=["presenter", "movie_name", "average_vote", "genre_name"], value_vars=["amount_wertvoll_1","amount_gut_2" ,"amount_okay_3", "amount_schlecht_4", "amount_grottig_5"], var_name="vote" ,value_name="value")

print(movie_select_pie_format)

and voila:

I will try later if the pie-chart works with the altered dataframe…but it is looking much better and I am looking forward.

Edit:

It is working!
Thanks @cualr for your help with providing the missing infos!

movie_select_pie_format = movie_select

movie_select_pie_format = pd.melt(movie_select_pie_format, id_vars=["presenter", "movie_name", "average_vote", "genre_name"], value_vars=["amount_wertvoll_1","amount_gut_2" ,"amount_okay_3", "amount_schlecht_4", "amount_grottig_5"], var_name="vote" ,value_name="value")

print(movie_select_pie_format)
moviename_filtered = movie_select_pie_format.iat[0,1]

pie_chart = px.pie(movie_select_pie_format,
                   title=f"Stimmenverteilung von {moviename_filtered}",
                   values="value",
                   color="vote",
                   color_discrete_map={ 'amount_wertvoll_1':'darkgreen',
                                        'amount_gut_2':'lime',
                                        'amount_okay_3':'yellow',
                                        'amount_schlecht_4':'orange',
                                        'amount_grottig_5':'red'},
                   names="vote"
                  )

st.plotly_chart(pie_chart)

1 Like