plotly / plotly/plotly.py

px.strip jitter doesn't work as expected due to underlying go.Box config

Ouverte
#4,563 1 commentaire 1 réaction 1 personne assignée Voir sur GitHub

@archmoj y travaille déjà.

Depuis le 27/5/2024.

bug P3 sev-3
Langage dominant
Python
Étoiles
18.8k
Forks
2.8k
Merge moyen
16 h 26 min
PR mergées (30 j)
21

Description

Because of the way px.strip works under the hood (generates a go.Box() with the fill color rgba set to 0,0,0,0 and the width set to None), there does not appear to be currently any way to adjust the jitter in a multi-category strip plot. One would think that adding the jitter parameter to the trace_patch would allow this parameter to pass through, but because go.Box "jitter [is] of width equal to the width of the box(es)", this makes the jitter appear to stay at 0 even when set to 1, because the width of the boxes is None. Adding a box width to the go.Box traces causes the invisible boxes to push the jittered points over to one side.

Screenshot 2024-03-31 at 1 31 09 PM

Example to reproduce:

import plotly.express as px
import plotly.graph_objects as go
import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
import pandas as pd
import numpy as np

# Sample Data
df = pd.DataFrame({
    'Group ID': ['A', 'A', 'B', 'B', 'C', 'C']*100,
    'Entity ID': ['M1', 'M2', 'M1', 'M2', 'M1', 'M2']*100,
    'Value': np.random.randn(600)
})

# Create a colormap
def get_hex_color(value):
    rgba_color = plt.get_cmap('coolwarm')(mcolors.Normalize(vmin=df['Value'].min(), vmax=df['Value'].max())(value))
    return mcolors.to_hex(rgba_color)
colormap = {value: get_hex_color(value) for value in df['Value'].unique()}

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

# Basic example
fig = px.strip(df, x='Group ID', y='Value', color='Value', color_discrete_map=colormap)
fig.update_traces(marker=dict(size=10, opacity=0.8, line=dict(width=1, color='DarkSlateGrey')))

# Desired behavior (this does not work):
fig.update_traces(jitter=0.1) # We would expect this to have a small amount of jitter; instead, there is a lot

# Let's try extracting the data from the plotly express figure
list(fig.data)
for box in fig.data:
    box.update(jitter=0.9) # We would expect this to have a lot of jitter, but there appears to be none
new_fig = go.Figure(fig.data)

# This is probably because the go.Box width is None; let's try adding a width param
add_width = go.Figure(fig.data).update_traces(width=20, jitter=1)

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

# Styling (ignore)
fig.update_layout(showlegend=False, title='Basic Colored Grouped Strip Plot', template='plotly_white', width=300, height=200, margin=dict(l=0, r=0, b=0, t=40), xaxis_visible=False)
fig.add_annotation(text='<b>update_traces(jitter=0.1)</b><br>We would expect this<br>to have a small amount of jitter;<br>instead, there is a lot', x=0.5, y=0.5, xref='paper', yref='paper', showarrow=False, bgcolor='white', bordercolor='#999', opacity=0.8)
new_fig.add_annotation(text='<b>for box in fig.data:<br>box.update(jitter=0.9)</b><br>We would expect this<br>to have a lot of jitter,<br>but there appears to be none', x=0.5, y=0.5, xref='paper', yref='paper', showarrow=False, bgcolor='white', bordercolor='#999', opacity=0.8)
new_fig.update_layout(showlegend=False, title='Fig.data extracted from px.strip', template='plotly_white', width=300, height=200, margin=dict(l=0, r=0, b=0, t=40), xaxis_visible=False)
add_width.layout=new_fig.layout
add_width.update_layout(title='Adding a width param to the traces')
# Remove the annotation:
add_width.layout.annotations = [new_fig.layout.annotations[0].update({'text':'<b>update_traces(width=20, jitter=1)</b><br>Giving the boxes a width<br>just shifts everything over'})]
for demo in [fig, new_fig, add_width]: demo.show(config = {'displayModeBar': False})

Guide de contribution

Ouvrir le guide de contribution

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Évaluation

Cette issue n'a pas encore été évaluée.

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.