1

I have a scatter plot made using plotly.py and I would like to color certain points in the scatter plot with a different color based on a certain condition. I have attached a sample code below :

import plotly.plotly as py
import plotly.graph_objs as go
from plotly.offline import plot

data = [4.1, 2.1, 3.1, 4.4, 3.2, 4.1, 2.2]

trace_1 = go.Scatter(
    x = [1, 2, 3, 4, 5, 6, 7],
    y = data
)

layout = go.Layout(
    paper_bgcolor='rgb(255,255,255)',
    plot_bgcolor='rgb(229,229,229)',
    title = "Sample Plot",
    showlegend = False,
    xaxis = dict(
        mirror = True,
        showline = True,
        showticklabels = True,
        ticks = 'outside',
        gridcolor = 'rgb(255,255,255)',
    ),
    yaxis = dict(
        mirror = True,
        showline = True,
        showticklabels = False,
        gridcolor = 'rgb(255,255,255)',
    ),
    shapes = [{
            'type': 'line',
            'x0': 1,
            'y0': 4,
            'x1': len(data),
            'y1': 4,
            'name': 'First',
            'line': {
                'color': 'rgb(147, 19, 19)',
                'width': 1,
                'dash': 'longdash'
            }
        }, 
        {
            'type': 'line',
            'x0': 1,
            'y0': 3,
            'x1': len(data),
            'y1': 3,
            'line': {
                'color': 'rgb(147, 19, 19)',
                'width': 1,
                'dash': 'longdash'
            }
        }
    ]
)

fig = dict(data = [trace_1], layout = layout)
plot(fig, filename = "test_plot.html")

Here's the output Output Scatter plot

Here the long dashed horizontal lines have corresponding x values 4 & 3 respectively. As one can see, points 1, 2, 4, 6 and 7 lie outside the dashed lines. Is there a way to color them differently based on the condition (x > 3) and (x<4).

Here's a reference to something I found while searching for a solution : Python Matplotlib scatter plot: Specify color points depending on conditions

How can I achieve this in plotly.py ?

Ashwin Shenoy
  • 661
  • 5
  • 8

1 Answers1

5

You can accomplish this by using a numeric array to specify the marker color. See https://plot.ly/python/line-and-scatter/#scatter-with-a-color-dimension.

Adapting your particular example to display red markers below 3, green markers above 4, and gray markers between 3 and 4:

import plotly.graph_objs as go
from plotly.offline import init_notebook_mode, iplot
init_notebook_mode()

data = [4.1, 2.1, 3.1, 4.4, 3.2, 4.1, 2.2]

color = [
    -1 if v < 3 else 1 if v > 4 else 0
    for v in data
]

colorscale = [[0, 'red'], [0.5, 'gray'], [1.0, 'green']]

trace_1 = go.Scatter(
    x = [1, 2, 3, 4, 5, 6, 7],
    y = data,
    marker = {'color': color,
              'colorscale': colorscale,
              'size': 10
             }
)

layout = go.Layout(
    paper_bgcolor='rgb(255,255,255)',
    plot_bgcolor='rgb(229,229,229)',
    title = "Sample Plot",
    showlegend = False,
    xaxis = dict(
        mirror = True,
        showline = True,
        showticklabels = True,
        ticks = 'outside',
        gridcolor = 'rgb(255,255,255)',
    ),
    yaxis = dict(
        mirror = True,
        showline = True,
        showticklabels = False,
        gridcolor = 'rgb(255,255,255)',
    ),
    shapes = [{
            'type': 'line',
            'x0': 1,
            'y0': 4,
            'x1': len(data),
            'y1': 4,
            'name': 'First',
            'line': {
                'color': 'rgb(147, 19, 19)',
                'width': 1,
                'dash': 'longdash'
            }
        }, 
        {
            'type': 'line',
            'x0': 1,
            'y0': 3,
            'x1': len(data),
            'y1': 3,
            'line': {
                'color': 'rgb(147, 19, 19)',
                'width': 1,
                'dash': 'longdash'
            }
        }
    ]
)

fig = dict(data = [trace_1], layout = layout)
iplot(fig)

Example figure

Hope that helps!

Jon Mease
  • 319
  • 2
  • 4
  • Thanks a lot for answering Jon, that's exactly what I wanted. – Ashwin Shenoy Jun 03 '19 at 12:59
  • Great! Would you mind accepting the answer in that case? – Jon Mease Jun 03 '19 at 13:27
  • Also is it possible to annotate these points based on the conditions ? – Ashwin Shenoy Jun 03 '19 at 13:34
  • Sorry about not accepting the answer. I have used StackOverflow extensively but this is the my first time of asking a question. – Ashwin Shenoy Jun 03 '19 at 13:35
  • What kind of annotation do you have in mind? You could add a colorbar (https://plot.ly/python/colorscales/). – Jon Mease Jun 03 '19 at 13:48
  • Sorry for not being specific. By annotations, I mean that all the green points should have one text above them, same for all red and gray points (By referring your answer). E.g. All the green points having the text 'g' above them and the like for the other two. – Ashwin Shenoy Jun 03 '19 at 13:57
  • 1
    In the code example you have provided, -1 is assigned to any data point in the data list below 3 but I can't see any corresponding value in the color scale. Same for 0.5 and gray ? – Ashwin Shenoy Jun 06 '19 at 04:45