Scatter plotting Multiple Y-values for a single X. Traces give line graph

I have 4 dataframes that each contain 24 by 24 entries. I would like to plot one column (24 values) of each dataframe (the first, and then successively the rest) onto one x value. I can do that when I plot each dataframe separately onto separate graphs, but when I put them all into one long DF I get a mismatched length error.

Is it possible to do this?

Secondly, if I try to solve this issue by using traces, my scatter plots turn out really weird, I get a single y=x line plot with all the values bunched up as ticks either side of the y axis.

Hereโ€™s my code:

import plotly.io as io
io.renderers.default='browser'

# Create figure with secondary y-axis
fig = make_subplots(specs=[[{"secondary_y": True}]])

# Add traces
fig.add_trace(
    go.Scatter(x=time_Range , y=df_aT, name="P1"),
    secondary_y=False,
)

fig.add_trace(
    go.Scatter(x=time_Range, y=df_bT, name="P2"),
    secondary_y=True,
)

# Add figure title
fig.update_layout(
    title_text="Forecast pool distribution (01/01/2023)"
)

# Set x-axis title
fig.update_xaxes(title_text="MTU")

# Set y-axes titles
fig.update_yaxes(title_text="<b>primary</b> Pool 1", secondary_y=False)
fig.update_yaxes(title_text="<b>secondary</b> Pool 2", secondary_y=True)

fig.show()

However, if I select just one column from the DF, I can plot the values, but it comes out as a line plot, not scattered points!

Please send Help.

Hi @tg550 !

Your issue is all in data preparation, but without any data sample at least, it is hard to help!
Can you provide a sample of your data structure and how you โ€œput them all into one long DFโ€ ?

For your last issue, try to set mode=โ€˜markersโ€™ in your go.Scatter()

Thanks Skiks, I just concatenate the existing dfโ€™s, an example one would simply be

import pandas as pd
import numpy as np

df1 = pd.DataFrame(np.random.random((24, 24)))
df2 = pd.DataFrame(np.random.random((24, 24)))
df3 = pd.DataFrame(np.random.random((24, 24)))
df4 = pd.DataFrame(np.random.random((24, 24)))

df5 = [df,df2,df3,df4]
result = pd.concat(df5)

list1 = ['MTU_' + str(n) for n in range(1,25)]

result.columns = list1

Solution was provided on stack overflow by StephanT, albeit with first converting a dictionary to a dataframe, the solution still works though.

import pandas as pd
import numpy as np
import plotly.graph_objects as go

MTU_1 = [1,2,3]
MTU_2 = [4,5,6]
MTU_3 = [7,8,9]

MTUS = {'A':MTU_1,'B':MTU_2, 'C':MTU_3}

df = pd.DataFrame(MTUS)  # convert to DataFrame

cmin = min(np.hstack(df.values))  # get minimum value of the whole set
cmax = max(np.hstack(df.values))  # get maximum value of the whole set

fig = go.Figure()

for c in df.columns:
    fig.add_trace(
        go.Scatter(
            x=[c]*len(df[c]),  # construct list of identical X values to match the Y-list
            y=df[c],  # Your MTU list
            mode='markers',  # scatter plot without lines
            marker=dict(
                color=df[c],  # set color by the value of Y
                cmin=cmin,  # absolute color scaling min value
                cmax=cmax,  # absolute color scaling max value
                ),
                name=c,
            )
            )

fig.update_layout(height=500, width=500)
fig.show()

Hi @tg550 !

Not sure how that solve your initial issue, but if youโ€™re happy with it :ok_hand:

Then you should try it out!