Is it possible to set the distance between xaxis ticks as a function of data density between 2 ticks?

Hello there :slight_smile:

I’m making a come-back on this dear forum, as I’m wondering whether anyone here around already found a solution to the issue I’m trying to fix.

I’m plotting a Scatter/Bubble plot, where my data are like:
x= [10%, 11%, 12%, 13%, 15%, 20%, 45%, 48%,50%, 95%,96%,97%]
y= [1, 1.5, 2, 2.4, 2.8, 4, 4.1, 4.2, 4.3, 5, 5.5,6]
z= [100, 125, 150,200,140,160,170,186,124,114,115,164]

So, I have several data points between 10% and 15%, nothing between 20% and 45%, some between 45% and 50%, and the rest above 95%.
Similarly, I have a higher density between 1 and 3, and between 4 and 6, than I have between 3 and 4, on the y axis.

Given that I have a text on each of this bubble, whose area’s size is determined by the z array, it’s not very readable. If I could “shrink” the distance between the 3 and 4 on the y axis, and/or between 20 and 45% on the x axis, it would probably be much better.

Is there a way to do that dynamically, or to “cut” the axis & the graph when there is no data between 2 ticks?

Hi @David22, and welcome back to the forum :slight_smile:

Would something as simple as evenly spaced ticks on the x axis work for you?


import dash
import dash_html_components as html
import dash_core_components as dcc
import plotly_express as px
import pandas as pd

data = dict(
    [
        ("x_labels", ["10%", "11%", "12%", "13%", "15%", "20%", "45%", "48%", "50%", "95%", "96%", "97%"]),
        ("y", [1, 1.5, 2, 2.4, 2.8, 4, 4.1, 4.2, 4.3, 5, 5.5, 6]),
        ("z", [100, 125, 150, 200, 140, 160, 170, 186, 124, 114, 115, 164]),
    ]
)

df = pd.DataFrame(data)
df["x"] = df.index

fig = px.scatter(df, x="x", y="y", size="z", hover_data=["z"])
fig.update_layout(
    xaxis_tickmode="array", xaxis_tickvals=df["x"], xaxis_ticktext=df["x_labels"]
)

app = dash.Dash()
app.layout = html.Div([dcc.Graph(figure=fig)])

if __name__ == "__main__":
    app.run_server(debug=True)

image

@AnnMarieW Thanks for the hint.

I had to make use of

'xaxis':{
    'type':'category',
    'tickmode': 'array',
    'categoryorder': 'array',
    'categoryarray': mydataOnXaxis
}

in my layout, on both the x and y axis, to get a similar result.

The single issue I have with this solution is that I lose a bit of information regarding the density/clustering of data. Best and Worst performers are not immediately noticeable anymore, because their respective ticks is just “on tick further”, when considering the previous one. (On the above example, 95% is almost 2x better than the datapoint plotted on the 50% tick, but it’s not immediately noticeable.)

I will try to find a slighlty better solution. If I found one, I will post it here.

Thanks for your solution.