2

I have a scatter plot that is running on Plotly dash. This is the code:

import dash
import dash_core_components as dcc
import dash_html_components as html
import plotly
import plotly.graph_objs as go
from plotly.subplots import make_subplots
import numpy as np

fig = make_subplots(rows=2, cols=3, vertical_spacing=0,
                    horizontal_spacing=0.05, shared_xaxes=True, shared_yaxes=False)
fig.add_trace(go.Scatter(x=list(range(40)), y=np.random.randint(20, 40, 40), line_color='#fae823', showlegend=False,
                         hovertemplate=[], xaxis='x1', yaxis='y1'), row=1, col=1)
fig.add_trace(go.Scatter(x=list(range(40)), y=np.random.randint(100, 140, 40), line_color='#fae823', showlegend=False,
                         hovertemplate=[], xaxis='x2', yaxis='y2'), row=1, col=2)
fig.add_trace(go.Scatter(x=list(range(40)), y=np.random.randint(20, 40, 40), line_color='#fae823', showlegend=False,
                         hovertemplate=[], xaxis='x3', yaxis='y3'), row=1, col=3)
fig.add_trace(go.Scatter(x=list(range(40)), y=np.random.randint(20, 40, 40), line_color='#fae823', showlegend=False,
                         hovertemplate=[], xaxis='x4', yaxis='y4'), row=2, col=1)
fig.add_trace(go.Scatter(x=list(range(40)), y=np.random.randint(100, 140, 40), line_color='#fae823', showlegend=False,
                         hovertemplate=[], xaxis='x5', yaxis='y5'), row=2, col=2)
fig.add_trace(go.Scatter(x=list(range(40)), y=np.random.randint(20, 40, 40), line_color='#fae823', showlegend=False,
                         hovertemplate=[], xaxis='x6', yaxis='y6'), row=2, col=3)
fig.add_shape(go.layout.Shape(type='line', yref='y3', xref='x3', x0=0, x1=30, y0=30, y1=30,
                          line=dict(color='red', width=3)))

fig.update_layout({'plot_bgcolor': "#21201f", 'paper_bgcolor': "#21201f", 'legend_orientation': "h"},
                  legend=dict(y=1, x=0),
                  font=dict(color='#dedddc'), dragmode='pan', hovermode='x unified',
                  margin=dict(b=20, t=0, l=0, r=40))

fig.update_xaxes(showgrid=False, zeroline=False, rangeslider_visible=False, showticklabels=False,
                 showspikes=True, spikemode='across', spikesnap='data', showline=False, spikedash='dash',
                 spikecolor='#ebeae8', spikethickness=0.5)
fig.update_yaxes(showgrid=False, zeroline=False, showticklabels=True, showline=False)

fig.update_traces(xaxis='x1', col=1)
fig.update_traces(xaxis='x2', col=2)
fig.update_traces(xaxis='x3', col=3)

app = dash.Dash(__name__)

app.layout = html.Div(children=[
    dcc.Graph(id='chart1', figure=fig,

              config={'displayModeBar': False})
])

if __name__ == '__main__':
    app.run_server(debug=True, dev_tools_ui=False, dev_tools_props_check=False)

It draws the line for this particular subplot. enter image description here

However, if I change the xref and yref to subplots of the second row (for example xref='x4' and yref='y4') It doesn't work anymore. I tried the answer from this question.enter image description here

Another problem that I have that could be related to the above issue is that the ylabels for the second row are not the same as of first row. I want them to be like the first row. I highlighted what I mean in the figure below. enter image description here

Amir
  • 978
  • 1
  • 9
  • 26
  • What eould you like to achieve with these :`fig.update_traces(xaxis='x3', col=3)`? It messes up the axis notations. – vestland May 25 '20 at 13:31
  • 1
    @vestland Yes. I just figure it out right now that this is the problem. You remember that crosshair? It is related to that. In this chart I want to see three different stocks in three columns. So for each column I want a crosshair. So for each columns I set x axis . – Amir May 25 '20 at 13:35
  • Yes, I remember the crosshair. I'll take a look at this too when I find the time. – vestland May 25 '20 at 13:58
  • @vestland I just updated my code. I think I forgot to add the line that is in the chart. Now it is OK. Tanx. – Amir May 25 '20 at 14:00

1 Answers1

3

The code below takes a data sample similar to yours, calculates the mean for each column, and adds that as a horizontal line to each subplot to produce this plot:

enter image description here

I've removed some elements from your original snippet that seemd to mess up things. I've also ignored the dash elements since they're not necessary to produce a minimal reproducible example.

Code:

#import dash
#import dash_core_components as dcc
#import dash_html_components as html
import plotly
import plotly.graph_objs as go
from plotly.subplots import make_subplots
import numpy as np
import pandas as pd

np.random.seed(123)
df=pd.DataFrame({ 'x':list(range(40)),
                    'y1':np.random.randint(20, 40, 40),
                    'y2':np.random.randint(100, 140, 40),
                    'y3':np.random.randint(20, 40, 40),
                    'y4':np.random.randint(20, 40, 40),
                    'y5':np.random.randint(100, 140, 40),
                    'y6':np.random.randint(20, 40, 40)})
df.set_index('x')

fig = make_subplots(rows=2, cols=3, vertical_spacing=0.1,
                    horizontal_spacing=0.1, shared_xaxes=True, shared_yaxes=False)

fig.add_trace(go.Scatter(x=list(range(40)), y=df['y1'], line_color='#fae823', showlegend=False,
                         hovertemplate=[], xaxis='x1', yaxis='y1'), row=1, col=1)

fig.add_trace(go.Scatter(x=list(range(40)), y=df['y2'], line_color='#fae823', showlegend=False,
                         hovertemplate=[], xaxis='x2', yaxis='y2'), row=1, col=2)

fig.add_trace(go.Scatter(x=list(range(40)), y=df['y3'], line_color='#fae823', showlegend=False,
                         hovertemplate=[], xaxis='x3', yaxis='y3'), row=1, col=3)

fig.add_trace(go.Scatter(x=list(range(40)), y=df['y4'], line_color='#fae823', showlegend=False,
                         hovertemplate=[], xaxis='x4', yaxis='y4'), row=2, col=1)

fig.add_trace(go.Scatter(x=list(range(40)), y=df['y5'], line_color='#fae823', showlegend=False,
                         hovertemplate=[], xaxis='x5', yaxis='y5'), row=2, col=2)

fig.add_trace(go.Scatter(x=list(range(40)), y=df['y6'], line_color='#fae823', showlegend=False,
                         hovertemplate=[], xaxis='x6', yaxis='y6'), row=2, col=3)

fig.update_layout({'plot_bgcolor': "#21201f", 'paper_bgcolor': "#21201f", 'legend_orientation': "h"},
                  legend=dict(y=1, x=0),
                  font=dict(color='#dedddc'), dragmode='pan', hovermode='x unified',
                  margin=dict(b=20, t=0, l=0, r=40))

fig.update_xaxes(showgrid=False, zeroline=False, rangeslider_visible=False, showticklabels=False,
                 showspikes=True, spikemode='across', spikesnap='data', showline=False, spikedash='dash',
                 spikecolor='#ebeae8', spikethickness=0.5)

fig.update_yaxes(showgrid=False, zeroline=False, showticklabels=True, showline=False)

# add shapes
col_count = 1
for i in range(1,3):
    for j in range(1,4):
        fig.add_shape(go.layout.Shape(type="line",
                                        yref="paper",
                                        xref="x",
                                        x0=1,
                                        y0=df.iloc[:, col_count].mean(),
                                        x1=40,
                                        y1=df.iloc[:,col_count].mean(),
                                        #line=dict(color="RoyalBlue", width=3),),
                                        line=dict(color='red', width=3),),
                      row=i,
                      col=j)
        col_count = col_count+1

#fig.update_traces(xaxis='x1', col=1)
#fig.update_traces(xaxis='x2', col=2)
#fig.update_traces(xaxis='x3', col=3)
fig.show()
vestland
  • 55,229
  • 37
  • 187
  • 305
  • 1
    Thanks for your try. As you pointed out in the comments, the problem is probably in the `fig.update_traces`. Considering that, I need to edit my question to better demonstrate what I need. If I remove those `fig.update_traces` the corsshair would be removed. So thumbs up to you for your help. I will inform you in the comments when I finished editing my post. Really appreciate your help. – Amir May 25 '20 at 14:22
  • @Amir I see... Well at least my approach answered your question as it was asked. I'll keep working on the details. – vestland May 25 '20 at 14:31
  • You're right. I accepted it. And I will ask another question. Points for you buddy. You are amazing =) – Amir May 25 '20 at 14:35
  • @Amir Thanks! Focused questions normally attract better answers, so that's a good idea! – vestland May 25 '20 at 14:49