Skip to content

support arrays of color and colorscale for line and fillcolor of plotly.graph_objects.Scatter #5259

Open
@jleaves

Description

@jleaves

Coming from plotly.py. Since this is about the plotly.graph_objects module, the issue is posted here.

Currently, only plotly.graph_objects.Scatter.marker, plotly.graph_objects.Scatter.marker.gradient and plotly.graph_objects.Scatter.marker.line supports assigning colors by arrays of color along with colorscale.

Could the same color-setting techniques be allowed for plotly.graph_objects.Scatter.line and plotly.graph_objects.Scatter.fillcolor as well?

p.s. Links to the current documentation:

  1. The following supports arrays of color with colorscale:
  1. The following doesn't support arrays of color with colorscale:

Activity

nicolaskruchten

nicolaskruchten commented on Nov 10, 2020

@nicolaskruchten
Contributor

These are both good ideas although a bit trickier to implement because these arrays wouldn't have the same lengths as the others in the trace: the line.color would be 1 element shorter, and the fillcolor one would be different again. I'm actually not clear what kind of plot you'd like to make with variable fillcolor :)

alexcjohnson

alexcjohnson commented on Nov 10, 2020

@alexcjohnson
Collaborator

I'm guessing the variable fillcolor would be like https://stackoverflow.com/a/59950664/9188800
Q6kC7gQ

The line case is covered in #581 - short answer: big pain in SVG, more manageable in scattergl. I'd say the same goes for variable fillcolor

@nicolaskruchten I guess it could either be 1 element shorter or the same length, depending on exactly what you want the color to mean, and whether you want a smooth variation or a single color per segment. There may be use cases for both, and neither is particularly easy in SVG.

jleaves

jleaves commented on Nov 22, 2020

@jleaves
Author

These are both good ideas although a bit trickier to implement because these arrays wouldn't have the same lengths as the others in the trace: the line.color would be 1 element shorter, and the fillcolor one would be different again. I'm actually not clear what kind of plot you'd like to make with variable fillcolor :)

Sorry for the late reply.

I was trying to plot shapes with different colors. Each polygon (plotly.graph_objects.Scatter.fillcolor) comes with a numeric property which I want to illustrate by the "fill" color. Furthermore, the common boundary of two polygons (plotly.graph_objects.Scatter.line) also has a numeric property which I want to illustrate (now maybe by "width", but support for "color" may be helpful as well).

The simplist graph would look like this:

newplot

Currently, I have to write my own "color mapping" function, something like the function map_z2color in this section. With regards to my specific application, I successfully work around this issue with the above method.

But still, I guess my naive method may have performance issues as I have to manually produce a string of color for every polygon and every boundary. So maybe the "feature request" is still a good improvement? Any suggestions?

ryani

ryani commented on Dec 21, 2020

@ryani

I'm also interested in this feature. I'd like the lines to change color via something like the heatmap z component. I'd actually prefer gradient lines (blending between the values at each point) but using the z value of the start or end point would be fine.

My use case is scatter lines representing 2d data over time, and I want the trail to fade out as the points get further in the past.

yotkadata

yotkadata commented on Aug 15, 2023

@yotkadata

It would be really great to be able to use arrays/lists of colors for line and fillcolor. I am currently working on an interactive version of my MeteoHist App and I could've really used this feature. Instead, I ended up adding 365 traces to my Plot - one for every day of the year. This might serve as a workaround for others:

With a bar chart, I could get more or less what I want in one trace (code from inside a class):

# Define opacity depending on whether peak alpha is enabled
opacity = (
    self.df_t[f"{self.year}_alpha"]
    if self.settings["peak_alpha"]
    else np.ones(len(self.df_t))
)

# Get colorscale from method
# Results in an array of colors the same length as self.df_t
colors = self.get_colorscale()

# Display a simpler and faster plot if chart_type is "bar"
if chart_type == "bar":
    fig.add_trace(
        go.Bar(
            x=self.df_t["date"],
            y=self.df_t[f"{self.year}_diff"],
            base=self.df_t["mean"],
            marker=dict(
                color=colors,
                line_width=0,
                opacity=opacity,
            ),
        )
    )

    return fig

key-west-united-states-temperature-mean-2023-ref-1961-1990-interactive

But I like much better to draw an area between the mean and the current value. Since I can't use the color array directly, I have to create many "shapes" (actually they are Scatter traces):

# For each day, add a filled area between the mean and the year's value
for i in range(len(self.df_t) - 1):
    # Define x and y values to draw a polygon between mean and values of today and tomorrow
    date_today = self.df_t["date"].iloc[i]
    date_tomorrow = self.df_t["date"].iloc[i + 1]
    mean_today = self.df_t["mean"].iloc[i]
    mean_tomorrow = self.df_t["mean"].iloc[i + 1]
    value_today = self.df_t[f"{self.year}"].iloc[i]
    value_tomorrow = self.df_t[f"{self.year}"].iloc[i + 1]

    # If one day is above and the other below the mean, set the value to the mean
    if (value_today > mean_today) ^ (value_tomorrow > mean_tomorrow):
        value_tomorrow = mean_tomorrow

    fig.add_trace(
        go.Scatter(
            name=f"Daily value {self.df_t['date'].iloc[i].strftime('%d.%m.%Y')}",
            x=[date_today, date_today, date_tomorrow, date_tomorrow],
            y=[mean_today, value_today, value_tomorrow, mean_tomorrow],
            line_width=0,
            fill="toself",
            fillcolor=colors[i],
            showlegend=False,
            mode="lines",
            opacity=opacity[i],
            hoverinfo="skip",
        )
    )

return fig

key-west-united-states-temperature-mean-2023-ref-1961-1990-interactive

In the end this works, but it's quite slower performance-wise and also feels more "hacky".

self-assigned this
on Jul 5, 2024
removed their assignment
on Aug 2, 2024
changed the title [-][Feature Request] Support arrays of color and colorscale for line and fillcolor of `plotly.graph_objects.Scatter`[/-] [+]support arrays of color and colorscale for line and fillcolor of `plotly.graph_objects.Scatter`[/+] on Aug 9, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P3backlogfeaturesomething new

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @nicolaskruchten@gvwilson@alexcjohnson@ryani@yotkadata

        Issue actions

          support arrays of color and colorscale for line and fillcolor of `plotly.graph_objects.Scatter` · Issue #5259 · plotly/plotly.js