Trying to display all y-axis names in scatter chart even without data

I have a code that is keeping track of usernames and the time they logged in for a site, then display that on a scatter graph with the username being on the y-axis and the dates on the x. As this only tracks data for the past month, if there hasn’t been a log in from a particular username it doesn’t show that username in the y-axis. I have a list of all usernames, but I’m not sure how to use them here. Is there any way to display all of my available usernames in the y-axis of my scatter graph?

Here is my code.

        fig1 = px.scatter(userdb[userdb['date-time'] > (datetime.datetime.now() - pd.to_timedelta('30 days'))], x='date-time', y= 'Username', color = 'Username')

        fig1.update_xaxes(
            rangeselector=dict(
                buttons=list([
                    dict(count=1, label="1d", step="day", stepmode="backward"),
                    dict(count=7, label="1w", step="day", stepmode="backward"),
                    dict(step="all")
                ]),
                bgcolor = 'black'
            )

        )

        fig1.update_layout(
            title="Logins for last 30 days",
            xaxis_title="Date",
            yaxis_title="Users",
            height=450, #350
            showlegend=False
        )

Hello @ShreyanshG and welcome to the community.

Before looking at the code, may be you have to think again about the type of graph you want to use. Unfortunately a scatter plot is not appropriate for what you want to do. For a scatter plot both x and y axis should be quantitative .

2 Likes

Hi @ShreyanshG,

while @AbdelAnlah has a valid point, you could map your names to integers, plot these integers on the y-axis over the x-axis and use custom ticks to use the actual names. You could also map a color to each name.

import pandas as pd
import random
import plotly.express as px

random.seed(42)
days = 31

# create data
week = pd.date_range('01/01/2022', periods=days, freq='D')

# all names
all_names = list('ABCDEFGHIJKLMNOPQRSTUVWXYZ')

# current names in period
current_names = list('EFGHIJKXRQD')
current_names = [random.choice(current_names) for _ in range(days)]

# name mapping name --> int
name_map_dict = {n: i for n, i in zip(all_names, range(len(all_names)))}

# color mapping name -- color string
color_map_dict = {n: c for n, c in zip(all_names, px.colors.qualitative.Alphabet)}


# create DataFrame
df  = pd.DataFrame({'date': week, 'names': current_names})

# add columns with mapped entities
df['name_mapped_to_int'] = df.names.apply(lambda x: name_map_dict[x])
df['name_mapped_to_color'] = df.names.apply(lambda x: color_map_dict[x])


# create figure
fig = px.scatter(df, x='date', y='name_mapped_to_int')

# custom range and ticks
fig.update_layout({
    'yaxis': {
        'range': [0, len(all_names)],
        'tickmode': 'array',
        'tickvals': [*range(len(all_names))],
        'ticktext': all_names
    },
    'height': 600,
    'width': 600,
    'template': 'plotly_dark'
})

fig.update_traces(marker_color=df.name_mapped_to_color)

creates:

1 Like