Skip to main content
cancel
Showing results for 
Search instead for 
Did you mean: 

The Power BI DataViz World Championships are on! With four chances to enter, you could win a spot in the LIVE Grand Finale in Las Vegas. Show off your skills.

Reply
Flan
New Member

Python visuals doesn't work on online reading view but on desktop does

Hi everyone, 

 

Since a couple of day maybe week, i didn't noticed that one of my own python visual didn't work on the online version. On my dekstop app, nothing, it work well but only when i share the link and open it via my workspace the visual doesn't work anymore. 

there erreur that i have is this one : 

Script Runtime Error

[S-12c5e384-a869-4a16-9c4a-12dd6770c94c][S-12c5e384-a869-4a16-9c4a-12dd6770c94c]AttributeError: 'NoneType' object has no attribute 'points_to_pixels'
Please try again later or contact support. If you contact support, please provide these details.

Activity ID: fb2167c7-a9c2-4229-ba95-dd2df542479d
Request ID: d0f51534-072d-4d2e-a767-651859b64a82
Correlation ID: 101ac569-2fa3-434e-5997-79102e36e5a0
Time: Mon Dec 02 2024 18:25:33 GMT+0100 (Central European Standard Time)
Service version: 13.0.24766.27
Client version: 2411.3.21845-train
Cluster URI: https://wabi-west-europe-b-primary-redirect.analysis.windows.net/

 

 

My code is but i am not sure that it come from him because nothing change since a couple of months... 

import matplotlib.pyplot as plt
import pandas as pd
import matplotlib.dates as mdates
from matplotlib.dates import DateFormatter, MonthLocator

# Supposons que dataset soit un DataFrame pandas déjà défini
dataset['Date update'] = pd.to_datetime(dataset['Date update'])
dataset['Forecast'] = pd.to_datetime(dataset['Forecast'])

# Pivot table
pivot = pd.pivot_table(dataset, aggfunc='first', index='Date update', values='Forecast', columns='Milestones name')
fig, ax = plt.subplots(figsize=(12, 8))

# Plot each column
for column in pivot.columns:
    clean = pivot[[column]].dropna()
    ax.plot_date(clean.index, clean[column], xdate=True, ydate=True, ls='-', lw=1, label=column)

# Ajuster les limites des axes pour découpler Date update (axe x) et Forecast (axe y)
min_date_update = dataset['Date update'].min()
max_date_update = dataset['Date update'].max()

min_forecast = dataset['Forecast'].min()
max_forecast = dataset['Forecast'].max()

# Dates limites pour les axes
max_date_forecast = max(dataset['Forecast'])
next_year_forecast = max_date_forecast.year + 1
q1_next_year_forecast = pd.Timestamp(year=next_year_forecast, month=1, day=1)

min_date_forecast = min(dataset['Forecast'])
min_year_forecast = min_date_forecast.year
q1_actual_year_forecast = pd.Timestamp(year=min_year_forecast, month=1, day=1)

min_date_update = min(dataset['Date update'])
min_year_dateupdate = min_date_update.year
q1_actual_year_dateupdate = pd.Timestamp(year=min_year_dateupdate, month=1, day=1)

# Ajouter la ligne 45 degrés (y=x)
# Créer des listes de dates pour la ligne 45 degrés
line_dates = pd.date_range(start=q1_actual_year_dateupdate, end=q1_next_year_forecast, freq='D')
ax.plot(line_dates, line_dates, color='black', linestyle='--', label='')

# Coloration après les courbes
adjusted_min_date_update = q1_actual_year_dateupdate
adjusted_max_forecast = q1_next_year_forecast
if len(line_dates) > 0:
    ax.fill_between(line_dates, adjusted_min_date_update, line_dates, color='white', zorder=2)

# -----------------------------------------------------------------------------------------------

# Définir les localisateurs pour les mois (trimestres)

month_locator = MonthLocator(bymonth=[1, 4, 7, 10])

plt.gca().xaxis.set_major_locator(month_locator)
plt.gca().yaxis.set_major_locator(month_locator)

# Création du formateur personnalisé pour afficher les trimestres
class QuarterFormatter(DateFormatter):
    def __init__(self, fmt='%Y-%m', **kwargs):
        super().__init__(fmt, **kwargs)

    def __call__(self, x, pos=0):
        date = mdates.num2date(x)
        # Si c'est janvier, afficher l'année en dessous de Q1
        if date.month == 1:
            return f'{date.year} - Q1'
        elif date.month == 4:
            return 'Q2'
        elif date.month == 7:
            return 'Q3'
        elif date.month == 10:
            return 'Q4'
        return ''

# Appliquer le formateur de trimestre personnalisé
quarter_formatter = QuarterFormatter()
plt.gca().xaxis.set_major_formatter(quarter_formatter)
plt.gca().yaxis.set_major_formatter(quarter_formatter)

# -----------------------------------------------------------------------------------------------

# Rotation des étiquettes pour une meilleure lisibilité
plt.xticks(rotation=90, ha='center')

# Ajouter les lignes de grille pour les années uniquement
start_date_update = pd.Timestamp(year=q1_actual_year_dateupdate.year, month=1, day=1)
end_date_forecast = pd.Timestamp(year=q1_next_year_forecast.year, month=1, day=1)
for year in range(start_date_update.year, end_date_forecast.year):
    january_start = pd.Timestamp(year=year, month=1, day=1)
    ax.axvline(x=january_start, color='gray', linestyle='--', linewidth=0.5)
    ax.axhline(y=january_start, color='gray', linestyle='--', linewidth=0.5)

# -----------------------------------------------------------------------------------------------

# Ajuster les limites des axes
plt.xlim(q1_actual_year_dateupdate, q1_next_year_forecast)  # Limites pour l'axe des x (Date update)
plt.ylim(q1_actual_year_dateupdate, q1_next_year_forecast)   # Limites pour l'axe des y (Forecast)

# -----------------------------------------------------------------------------------------------
legend = ax.legend(loc='upper left', bbox_to_anchor=(1.01, 1), frameon=False)
# Ajuster la légende
def adjust_legend_fontsize(ax):
    legend = ax.get_legend()  # Récupère la légende existante
    if legend is None:  # Si aucune légende n'est définie, arrêter
        return 10

    fig = ax.get_window_extent()
    fig_height = fig.height 
    fontsize = 10
    adjusted = False
    while not adjusted:
        legend = ax.legend(loc='upper left', bbox_to_anchor=(1, 1), fontsize=fontsize)
        legend_bbox = legend.get_window_extent()
        legend_height = legend_bbox.height
        if legend_height <= fig_height:
            adjusted = True
        else:
            fontsize -= 1
            if fontsize < 8:
                break
    return fontsize
ax = plt.gca()
fontsize = adjust_legend_fontsize(ax)
myLegend = ax.legend(loc='upper left', bbox_to_anchor=(1.01, 1), frameon=False, fontsize=fontsize)

# Désactiver les ajustements automatiques des marges
plt.subplots_adjust(left=0.08, right=0.75, top=0.95, bottom=0.1)

# Afficher le graphique
plt.show()

 

If you have an idea, that coudl help me !! 
thanks you very much in advance, and have a nice day !

Flan

3 REPLIES 3
lbendlin
Super User
Super User

Maybe read through the release notes of these two libraries - could be that a recent version update has caused that.

Hi ! 
Unfortunately, even with librabries updated, it still doesn't work.
It's weird because others visual work so i guess there is an issue with this one in particular... 😞 

 

If you have a Pro license you can open a Pro ticket at https://admin.powerplatform.microsoft.com/newsupportticket/powerbi
Otherwise you can raise an issue at https://community.fabric.microsoft.com/t5/Issues/idb-p/Issues .

Helpful resources

Announcements
Feb2025 Sticker Challenge

Join our Community Sticker Challenge 2025

If you love stickers, then you will definitely want to check out our Community Sticker Challenge!

Jan NL Carousel

Fabric Community Update - January 2025

Find out what's new and trending in the Fabric community.

Top Solution Authors
Top Kudoed Authors