Figure Friday 2024 - week 46

hi @Keesh0826 ,
:wave: Welcome to the community. Your graph is a great start, and thank you for participating in Figure-Friday.

A few pointers:

  1. when posting your code, it’s better to share the whole code with the data set (a minimal reproducible example MRE), like I did in the first post. This will make it easy for community members to copy your code into their IDE and recreate the graph you built.
  2. You can probably remove the x-axis title color because it doesn’t add helpful information to the graph. Users will understand what the x-axis represents without the x-axis title.
  3. Is there a way to represent white wines with a different color that is closer to white? I read white but I see light blue, which kind of confused my brain :slight_smile:
  4. Are you 100% sure your figure is correct? Am I reading it correctly when I see that Italy’s white wine median max_yield_hl is about 130? I thought the median yield is around 80 :thinking:

I hope you can join our figure friday session next week where we’ll talk about the UFO data set :grinning:

Let me know if you’d like me to send you a calendar invite.

HI @natatsypora
This graph is amazing. So much rich information in one graph. Those dotted lines, do they represent the median or mean values?
Was there anything that stood out to you when working on this data set?

I hope you can join our figure friday session next week where we’ll talk about the UFO data set :grinning:

Let me know if you’d like me to send you a calendar invite.

1 Like

Hi @Snowmbird :wave: Welcome to the community.

I like the idea of using a sunburst for this data set. Are you able to control the colors or maybe make them more neutral. For me it was a bit confusing to see the color green but read white in the text, or see the color blue and read red in the text.

I hope you can join our figure friday session next week where we’ll talk about the UFO data set :grinning:

Let me know if you’d like me to send you a calendar invite.

Nice job @Alfredo49 . The bar chart is definitely easier to read than the scatter plot. Thanks for sharing your update.

Hi everyone,

Inspired by this week’s dataset post, I decided to try a box plot to explore the maximum allowed yield for different wine colors across countries. I really liked the pastel palette version of the graph that @Juleneurkidi used above, so I incorporated it into my visualization as well!

In the code, to make the graph better, I added jittered, semi-transparent points to reduce overlap and show individual data points more clearly. I also included the mean value within the box for better statistical insights.

Let me know what you think or if there are ways to improve it! :blush:


import plotly.express as px
import pandas as pd

# Load and clean the data
df = pd.read_csv("wine_data.csv")
df['Max_yield_hl'] = pd.to_numeric(df['Max_yield_hl'], errors='coerce')
df_cleaned = df.dropna(subset=['Max_yield_hl'])

fig = px.box(
    df_cleaned,
    x='Color',
    y='Max_yield_hl',
    color='Country',
    title="Box Plot of Max Allowed Yield by Wine Color and Country",
    labels={"Max_yield_hl": "Max Yield (hl/ha)", "Color": "Wine Color"},
    color_discrete_sequence=px.colors.qualitative.Pastel  # Use a subtle color palette
)

# Update layout for better presentation
fig.update_traces(
    boxmean=True,  # Display the mean value inside the box
    jitter=0.3,    # Add slight jitter to overlapping points
    marker=dict(opacity=0.6)  # Semi-transparent points
)

fig.update_layout(
    title_font_size=16,
    xaxis_title="Wine Color",
    yaxis_title="Max Yield (hl/ha)"
)

fig.show()

1 Like

Thank you! :pray: :blush:
I tried to add as much information as possible because the chart itself is difficult to understand.
People who are far from math or statistics don’t use metrics like IQR or KDE every day.

This line represents the mean values:

  • fig.update_traces(meanline_visible=True)

This week I was more into building graphs :woman_technologist:
Amazing infographic from the @U-Danny app caused a desire to repeat it using only Plotly.

Hi @Mike_Purtell ,
I tried to do something similar without Dash 

There are a lot of lines of code that can be optimized, but I like the result :upside_down_face:

Code
import plotly.express as px
import plotly.graph_objects as go
from plotly.subplots import make_subplots
import pandas as pd

from PIL import Image

glass_green = Image.open('/content/glass_green.png')
glass_blue = Image.open('/content/glass_blue.png')

df = pd.read_csv('https://raw.githubusercontent.com/plotly/Figure-Friday/refs/heads/main/2024/week-46/PDO_wine_data_IT_FR.csv')
df_gr = df.groupby('Country', as_index=False)['Color'].value_counts(normalize=True)

wine_colors = {'White':'white', 'Red':'crimson', 'Rosé':'pink'}
country_colors = {'FR':['France', '#004667', glass_blue], 'IT':['Italy', 'green', glass_green]}

bar_fr = px.bar(df_gr[df_gr['Country']=='FR'], 
                    x='Country', y='proportion', 
                    color='Color', custom_data='Color',
                    color_discrete_map=wine_colors,
                    opacity=0.8)

bar_it = px.bar(df_gr[df_gr['Country']=='IT'],
                    x='Country', y='proportion', 
                    color='Color', custom_data='Color',
                    color_discrete_map=wine_colors,
                    opacity=0.8)

# Create stacked bar chart with images for wine distribution by color and country

# Define Figure
fig = make_subplots(
    rows=1, cols=3, 
    horizontal_spacing=0,
    column_widths=[0.35, 0.3, 0.35],
    shared_yaxes=True)  

# Add traces for each country with stacked bars
for i in range(3):
    fig.add_trace(bar_fr.data[i], row=1, col=1)
    fig.add_trace(bar_it.data[i], row=1, col=3)    

fig.update_traces(
    width=0.64, 
    marker_cornerradius=80,    
    hovertemplate='Wine Color: %{customdata}<br>Percentage: %{y:.1%}<extra></extra>')

# Add text and images
for i, x in enumerate(['FR', 'IT']):  
    # Add additional bar for extending  yaxis
    fig.add_bar(x=[x], y=[1.2],
                width=0.1, hoverinfo='skip',
                marker=dict(color='rgba(0,0,0,0)', line_width=0),
                row=1, col=(i % 2) * 2 + 1,) 

    # Add name for each country as title   
    fig.add_scatter(x=[x], y=[-.2],  
                    mode='text', hoverinfo='skip',
                    text=country_colors[x][0], 
                    textfont=dict(size=20, color=country_colors[x][1]),
                    row=1, col=(i % 2) * 2 + 1,)
    
    # Add image above bars for each country  
    fig.add_layout_image(            
                source=country_colors[x][2],
                xref='x',
                yref='y',
                x=-0.4, y=-.12,
                sizex=.8, sizey=2.38,
                sizing='stretch', 
                opacity=1,
                layer='above', row=1, col=(i % 2) * 2 + 1,)
    
# Add text with percentage for France
fig.add_scatter(x=['FR']*3, y=[0.15, 0.5, 0.85],
                mode='text', hoverinfo='skip',
                text=df_gr[df_gr['Country']=='FR']['proportion'],
                texttemplate='%{text:.0%} &#x2003;', textposition='middle left',                
                marker_size=20,
                row=1, col=2) 

# Add text with percentage for Italy  
fig.add_scatter(x=['FR']*3,  y=[0.15, 0.5, 0.85],
                mode='text+markers',  hoverinfo='skip',
                text=df_gr[df_gr['Country']=='IT']['proportion'],
                texttemplate='&#x2003;%{text:.0%}', textposition='middle right',              
                marker=dict(color=['pink','crimson', 'white'], size=20, symbol='square'),
                row=1, col=2)  
                                       
fig.update_layout(
    title_text='Wine Distribution by Color', title_x=0.5, 
    width=700, height=500,
    xaxis_visible=False, showlegend=False,
    yaxis=dict(autorange='reversed', visible=False), 
    yaxis2_visible=False, xaxis2_visible=False,
    xaxis3_visible=False, yaxis3_visible=False,
    barmode='stack', font_size=16, font_weight='bold',
    margin=dict(l=10, t=70, r=10, b=10), hovermode='x',
    template='seaborn', paper_bgcolor='#EAEAF2')

fig.show()

Images for this graph
In addition to this, I want to show the chart without using images or icons .

Code
df_gr = df.groupby('Country', as_index=False)['Color'].value_counts(normalize=True).sort_values(by='proportion')

wine_colors = {'White':'white', 'Red':'crimson', 'Rosé':'pink'}

wine_glass = px.bar(df_gr[df_gr['Country']=='FR'],
                    x='Country', y='proportion',
                    custom_data='Color', 
                    color='Color', 
                    color_discrete_map=wine_colors, 
                    opacity=0.8)

# Update traces 
wine_glass.update_traces(
    marker=dict(cornerradius=70,            # Add rounded corners on the bars
                line_color='navy', 
                line_width=3),
    width=0.5, 
    hovertemplate='Wine Color: %{customdata}<br>Percentage: %{y:.0%}<extra></extra>')

# Add a leg for the wine glass (first part)
wine_glass.add_bar(x=['FR'], y=[1.2], width=0.1, marker_color='navy', hoverinfo='skip')

# Add a text label for the wine glass
wine_glass.add_scatter(x=['FR'], y=[-.2], mode='text', text='France', 
                       textfont=dict(size=20, color='navy'), hoverinfo='skip')

# Add the base for the leg of the wine glass
wine_glass.add_bar(x=['FR'], y=[0.1], width=0.3, base=2.1,
                   marker=dict(cornerradius=60, color='navy'), hoverinfo='skip')

# Update layout
wine_glass.update_layout(
    hovermode='x', barmode='stack', showlegend=False,
    xaxis_visible=False, 
    yaxis=dict(autorange='reversed', visible=False),    # Reverse the y-axis to obtain a rounding on the bottom side                  
    font_size=16, font_weight='bold',
    template='plotly_white',
    plot_bgcolor='#F7F7F7', paper_bgcolor='#F7F7F7',
    width=300, height=400,
    margin=dict(l=10, t=10, r=10, b=10))

wine_glass.show()

4 Likes

Hi @Mike_Purtell , no, it doesn’t actually depend on Dash; It is only with Plotly, specifically with px.imshow. The original idea is ‘Pictorial Chart’ type graphics. The approach is to generate an image with a range of colors depending on the data set in this case using SVG icons from FontAwesome. @natatsypora visualization is very good; Using images directly helps a lot to reduce processing time, if there is an image repository with these characteristics, it would be great to know about it.

4 Likes

Thanks :blush:

I use pictures on transparent background from this site :woman_technologist:

3 Likes

3 Likes

I’m loving all the entries this week - you’ve all done an awesome job! The wine glasses are super creative! :wine_glass: I didn’t even know you could do that with Plotly. It really shows how versatile the Plotly package is.

3 Likes