The ultimate Fabric, Power BI, SQL, and AI community-led learning event. Save €200 with code FABCOMM.
Get registeredCompete to become Power BI Data Viz World Champion! First round ends August 18th. Get started.
Hi everyone,
I'm going to try to explain in the best possible way my problem to see if someone can help or advise me. I am trying to create a Python visualization in Power BI from the data in my df and the plot pizza comparison code from mplsoccer: https://mplsoccer.readthedocs.io/en/latest/gallery/pizza_plots/plot_pizza_comparison.html
This is my df:
It has a total of 14 columns, the first 2 being the names of the players I want to compare in the visualization. I thought that making 2 columns with the same players maybe would be beneficial when working with slicers (one for Player 1 and one for Player 2) but I don't know if this is correct? If there is a way not to do it, I would appreciate some advice.
The next step I do is to create the Python object with this code:
import pandas as pd
import matplotlib.pyplot as plt
from highlight_text import fig_text
from mplsoccer import PyPizza, FontManager
import numpy as np
from scipy import stats
import math
import matplotlib.pyplot as plt
from highlight_text import fig_text
df = dataset
df = df.fillna(0)
params = list(df.columns)
params = params[2:]
jugador1 = df['Jugador 1'].reset_index()
#we pass player's 1 Values :
jugador1 = list(jugador1.loc[0])
jugador2 = df['Jugador 2'].reset_index()
#we pass player's 2 Values :
jugador2 = list(jugador2.loc[0])
#we slice the list to remove the index-index-name columns :
jugador1 = jugador1[3:]
jugador2 = jugador2[3:]
#calculate percentile score of the values compared to the original dataframe :
values1 = []
values2 = []
for x in range(len(params)):
values1.append(math.floor(stats.percentileofscore(df[params[x]],jugador1[x])))
for x in range(len(params)):
values2.append(math.floor(stats.percentileofscore(df[params[x]],jugador2[x])))
font_normal = FontManager('https://raw.githubusercontent.com/google/fonts/main/apache/roboto/'
'Roboto%5Bwdth,wght%5D.ttf')
font_italic = FontManager('https://raw.githubusercontent.com/google/fonts/main/apache/roboto/'
'Roboto-Italic%5Bwdth,wght%5D.ttf')
font_bold = FontManager('https://raw.githubusercontent.com/google/fonts/main/apache/robotoslab/'
'RobotoSlab%5Bwght%5D.ttf')
# instantiate PyPizza class
baker = PyPizza(
params=params, # list of parameters
background_color="#EBEBE9", # background color
straight_line_color="#222222", # color for straight lines
straight_line_lw=1, # linewidth for straight lines
last_circle_lw=1, # linewidth of last circle
last_circle_color="#222222", # color of last circle
other_circle_ls="-.", # linestyle for other circles
other_circle_lw=1 # linewidth for other circles
)
# plot pizza
fig, ax = baker.make_pizza(
values1, # list of values
compare_values=values2, # comparison values
figsize=(13,13), # adjust figsize according to your need
kwargs_slices=dict(
facecolor="#1A78CF", edgecolor="#222222",
zorder=2, linewidth=1
), # values to be used when plotting slices
kwargs_compare=dict(
facecolor="#FF9300", edgecolor="#222222",
zorder=2, linewidth=1,
),
kwargs_params=dict(
color="#000000", fontsize=12,
fontproperties=font_normal.prop, va="center"
), # values to be used when adding parameter
kwargs_values=dict(
color="#000000", fontsize=12,
fontproperties=font_normal.prop, zorder=3,
bbox=dict(
edgecolor="#000000", facecolor="cornflowerblue",
boxstyle="round,pad=0.2", lw=1
)
), # values to be used when adding parameter-values labels
kwargs_compare_values=dict(
color="#000000", fontsize=12, fontproperties=font_normal.prop, zorder=3,
bbox=dict(edgecolor="#000000", facecolor="#FF9300", boxstyle="round,pad=0.2", lw=1)
), # values to be used when adding parameter-values labels
)
# add title
fig_text(
0.515, 0.99, "Comparison between Player 1 and Player 2", size=17, fig=fig,
highlight_textprops=[{"color": '#1A78CF'}, {"color": '#EE8900'}],
ha="center", fontproperties=font_bold.prop, color="#000000"
)
plt.show()
I also create 2 independent slicers for Player 1 and another one for Player 2. That is, when choosing an option in Player 1, the slicer of Player 2 is not filtered and so I can choose another different player to compare their metrics.
However, the visualization gives me the following Keyerror 0:
I think I'm close to being able to achieve this, but something I'm failing at. could someone guide me to get a solution? Thank you very much in advance and best regards!
PS: It is worth clarifying that the Python directory is well configured in Power BI and that I am working with the latest Desktop version. Just in case, I show how is the dashboard currently:
I would create a table with 3 columns (player, metric, and value) by unpivoting your data. You can then use a slicer and some DAX logic to make sure only 2 players selected (or use 2 disconnected slicers).
For the visual, you could also consider building it with the low-code/no-code Charticulator or Deneb visuals.
Pat
Thanks for your answer. The fact is that I need to show exactly that visualization and I would like to learn how to work with slicers that interact with the Python visualization.
I think the key is in these lines of code:
jugador1 = df['Jugador 1'].reset_index()
#we pass player's 1 Values :
jugador1 = list(jugador1.loc[0])
jugador2 = df['Jugador 2'].reset_index()
#we pass player's 2 Values :
jugador2 = list(jugador2.loc[0])
#we slice the list to remove the index-index-name columns :
jugador1 = jugador1[3:]
jugador2 = jugador2[3:]
However, I don't know exactly what might be going wrong. I also tried removing .reset_index but it didn't work. It's something related to lists, ranges and index but I don't have the knowledge to find it. I tried to read in this topic to see if I could find a solution or try to adapt the code but it didn't help me.
Any other suggestions?