Set different value for x-axis on in bar-chart with facet_cols

I am displaying file sizes of data-records using a bar-chart with facet cols. However, on/below the x-axis the I would like the value to be changed to the information of a different column of my data.

In the chart it uses the value of “Type” , but it should be “File Size” instead. Given the following dataframe:

    Records   File Size        Type
0        50     3451984    Original
1       100     7238642    Original
2       123     5240073    Original
3       125     5324803    Original
4       250    10689882    Original
5       500    21359640    Original
6       750    39314972    Original
7      1000    65988805    Original
8      2500   137326129    Original
9      5000   409999768    Original
10    10000  1516573133    Original
11    12500   591099120    Original
12    15000  1543588299    Original
0        50     2595105  Compressed
1       100     6225535  Compressed
2       123     4944289  Compressed
3       125     5033015  Compressed
4       250    10109550  Compressed
5       500    20188200  Compressed
6       750    36525815  Compressed
7      1000    64701746  Compressed
8      2500   133568835  Compressed
9      5000   420708215  Compressed
10    10000  1529245863  Compressed
11    12500   568799152  Compressed
12    15000  1596295923  Compressed

with the following code:

            fig = px.bar(df, x="Type", y="Records", color="Type", barmode="group",
                          facet_col="Records",
                          category_orders={"File Size": df["File Size"],
                                           "Records": df["Records"]},
                          hover_data=["File Size","Records"])

I get this result:

The information on the x-axis below the bar is pretty redundant and somewhat useless as it’s indicated by color already whether it is compressed or original.
I would like to have the actual File Size written there.

Apparently this code from the tutorial changes something (that looks to me like the value below the 2nd bar but I am uncertain about it), but I can’t figure out how to properly change the values.

fig.update_layout(
    xaxis = dict(
        tickmode = 'array',
        tickvals = [1, 3, 5, 7, 9, 11],
        ticktext = ['One', 'Three', 'Five', 'Seven', 'Nine', 'Eleven']
    )
)

However I am not able to change anything meaningful

Apparently to some the picture is broken.

Here is a re-up:

hi @qohelet

How about something like this?

Click for Data File

import pandas as pd
import plotly.express as px

df = pd.read_csv('data-mario.csv')

fig = px.bar(df, y="Records", color="Type", barmode="relative",
                          category_orders={"File Size": df["File Size"],
                                           "Records": df["Records"]},
                          hover_data=["File Size","Records"])
fig.update_layout(
    xaxis = dict(
        tickmode = 'array',
        tickvals = list(range(26)),
        ticktext = df["File Size"]
    ),
    xaxis_title = ""
)

fig.show()
1 Like

First of all: Thank you for sharing my data as CSV, that makes it for testing much easier.

It’s pretty cool the way you did it - however I require compressed/original to be next to each other, otherwise the comparison doesn’t work too well.

I tried to use your approach on my given version and it kind of works at least on the first sample:
Selection_398

This is, despite not solving it (yet) by far better than most of my attempts.

hi @qohelet
I can’t get it to do what you want. I’ll keep trying. But how about something like this:

import pandas as pd
import plotly.express as px

df = pd.read_csv('data-mario.csv')

fig = px.bar(df, x="Type", y="Records", color="Type", barmode="group",
                          facet_col="Records", text='File Size',
                          category_orders={"File Size": df["File Size"],
                                           "Records": df["Records"]},
                          hover_data=["File Size","Records"])
fig.update_traces(texttemplate='%{text:.2s}', textposition='outside')

fig.show()

Nope, that’s something else. But your first post made me think and I realizes something I had overseen. Thank you for you input, I could solve the problem:

            half=int(len(df)/2)
            axies=[x for x in dir(fig.layout) if x.startswith("xaxis")]
            axies[0]='xaxis0'
            saxes=sorted(axies, key = lambda x: int(x.split("xaxis")[1]))
            saxes[0]='xaxis'

            execdictlist=[]
            
            for idx,axis in enumerate(saxes):
                execdictlist.append({axis:dict(
                    tickmode = 'array',
                    tickvals = list(range(26)),
                    ticktext = (df.iloc[idx,df.columns.get_loc("File Size")], #Original
                                df.iloc[half+idx,df.columns.get_loc("File Size")] #Compressed
                    )
                ),
                                     axis+"_title":""})

            for axis in execdictlist:
                fig.update_layout(
                    **axis              
                )

This is to be honest a little hacky, but it does solve all of my issues. If you have an additional improvement, I’d be glad to hear.
I wouldn’t have found that without your support.

2 Likes