plotly stacked area plot only shows four out of five traces

In the code below, I am plotting a stacked-area plot in plotly. For some reason only 4 out of the 5 traces are showing in the plot. Please help me figure out how to get the final trace to show.

Here is some working code to get the data for the plot:

<div id = "plot33"></div>
<script src="https://d3js.org/d3.v4.js"></script>
let txhousing
d3.csv("https://raw.githubusercontent.com/tidyverse/ggplot2/main/data-raw/tx-housing.csv", function(data){
    txhousing = data
})


// Filter cities as specified in the R code
var selectedCities = ["Austin", "Houston", "Dallas", "San Antonio", "Fort Worth"];
var filteredData = txhousing.filter(data => selectedCities.includes(data.city));

// Convert sales to numbers
filteredData.forEach(data => {
  data.sales = parseInt(data.sales, 10);
});

// Group and sum by city and year
var groupedData = {};

filteredData.forEach(data => {
    let key = data.city + '_' + data.year;
    if (!groupedData[key]) {
        groupedData[key] = {
            city: data.city,
            year: data.year,
            sales: 0
        };
    }
    groupedData[key].sales += data.sales;
});


var finalDataArray = Object.values(groupedData);
var citiesGrouped = {};

selectedCities.forEach(city => {
    citiesGrouped[city] = finalDataArray.filter(data => data.city === city);
});


// Multiple austin by 2 to make it stand out more
if (citiesGrouped.Austin) {
  citiesGrouped.Austin.forEach(entry => {
      entry.sales *= 2;
  });
}

And here is the plot code which is only showing 4 traces out of 5:


// Create an array to store the traces
var traces = [];

let urbanThemeYellow = "#fabd36"
let urbanThemeBlue = "#2e95cf"
let urbanThemeGray = "#d1d1d1"
let urbanThemePurple = "#e83b8a"
let urbanThemeBlack = "#000000"


// Add a trace for each city
selectedCities.forEach((city, index) => {
    let cityData = citiesGrouped[city];

    let trace = {
        x: cityData.map(data => data.year),
        y: cityData.map(data => data.sales),
        fill: 'tozeroy',
        type: 'scatter',
        mode: 'none',
        name: city
    };

    switch (city) {
        case 'Austin':
            trace.fillcolor = urbanThemeBlue;
            trace.line = {color: urbanThemeBlue};
            break;
        case 'Dallas':
            trace.fillcolor = urbanThemeYellow;
            trace.line = {color: urbanThemeYellow};
            break;
        case 'Fort Worth':
            trace.fillcolor = urbanThemeGray;
            trace.line = {color: urbanThemeGray};
            break;
        case 'Houston':
            trace.fillcolor = urbanThemePurple;
            trace.line = {color: urbanThemePurple};
            break;
        case 'San Antonio':
            trace.fillcolor="#FF6347"; // Replace with appropriate color if available
            trace.line = {color: '#FF6347'};
            break;
    }
    
    traces.push(trace);
});

// Define the layout
var layout = {
    showlegend: true, // Show legend
    legend: { "orientation": "h", y: -0.2 }, // Horizontal legend below the plot
    xaxis: {
        title: 'Year',
        tickvals: Array.from({length: 16}, (_, i) => 2000 + i),
    },
    yaxis: {
        title: 'Home sales',
        rangemode: 'tozero'
    }
};

// Plot the graph
Plotly.newPlot('plot33', traces, layout);

You can see the data for Austin is there, but the blue Austin color doesn’t show up on the plot. Why not?

Output plot

This is because all traces are set with fill: 'tozeroy' so they are not stacked but overlaid : the y’s don’t add up (if we comment out the switch block or use non-fully-opaque colors we can see that the traces are overlaid).

In order to properly stack them up you need to assign them to a stackgroup, traces in the same group fill up to the next trace of the group. Stacking also turns fill on by default, using "tonexty" (or "tonextx" if orientation is horizontal).

let trace = {
    x: cityData.map(data => data.year),
    y: cityData.map(data => data.sales),
    fill: 'tonexty',
    stackgroup: 'one',
    type: 'scatter',
    mode: 'none',
    name: city
};

Leave a Comment