Part 3 of 3: Controlling Plotly in React – Adding Custom Color Markers by Category

How to change the color of the markers based on arbitrary data categories

In this article, I will be showing you how to change the color of the markers depending on arbitrary data categories that could be associated with your data points.

You should already have a basic understanding of:

  • Javascript
  • Typescript
  • Plotly in react
  • React and React hooks

Steps in creating these custom annotations in plotly

  • Create starter app from Part 1 of this series
  • Create file to hold data
  • Create data categories and types
  • Create supporting data object
  • Add dropdown to select data category
  • Group the data by data category

Create starter app from Part 1 of this series

Go to part 1 of this 3 part series and follow the following steps:

  • Create the app in codesandbox.io
  • Import dependencies and starting code

Create file to hold data

Right click on the “src” directory and create a new file called “data.ts”

Create data categories and types

In data.ts, paste the following code:

export const sizeValues = ["small", "medium", "large", "extra large"] as const;
type Size = typeof sizeValues[number];
export const weightValues = [
 "light",
 "average",
 "heavy",
 "super heavy"
] as const;
type Weight = typeof weightValues[number];
export const lengthValues = ["short", "medium", "long", "extra long"] as const;
type Length = typeof lengthValues[number];
export const colorMap: { [x in Size | Weight | Length]: string } = {
 small: "green",
 light: "green",
 short: "green",
 medium: "red",
 average: "red",
 large: "blue",
 heavy: "blue",
 long: "blue",
 "extra large": "black",
 "super heavy": "black",
 "extra long": "black"
};
export type Data = {
 Size: Size;
 Weight: Weight;
 Length: Length;
};

Explanation of code

  • `sizeValues, weightValues, and lengthValues`: These arrays of strings contain the possible values for size, weight, and length. The reason we’re declaring these arrays of strings is because we want to iterate over them later, which we wouldn’t be able to do if we simply declared them as types.
  • `colorMap`: For each data value, we want the marker to display a specific color. This object contains the colors we want associated with each possible data value.
  • `Data`: This is the shape of the data we will associate with each data point

Create supporting data object

In App.tsx, add the following import statement at the top:

import { sizeValues, weightValues, lengthValues, Data, colorMap } from "./data";
Then, on the line above your App component declaration, add the following code:
const supportingData = getArray().map(
 () =>
   ({
     Size: sizeValues[getRandomNumber(sizeValues.length)],
     Weight: weightValues[getRandomNumber(weightValues.length)],
     Length: lengthValues[getRandomNumber(lengthValues.length)]
   } as Data)
);
//export default function App() {

Explanation of code

  • supportingData represents your arbitrary data that is associated with your data points. Each data point will have a random size, weight, and length associated with it.

Add dropdown to select data category

Inside the App component in App.tsx, paste the following hook at the top:

 const [dataType, setDataType] = useState<keyof Data>("Size");
Then, inside the JSX, paste the following dropdown:

// <div className="App">
     <div>
       <select
         value={dataType}
         onChange={(e) => setDataType(e.target.value as keyof Data)}
       >
         <option value="Size">Size</option>
         <option value="Length">Length</option>
         <option value="Weight">Weight</option>
       </select>
     </div>
     // <Plot
This will create a dropdown at the top of your application:

Explanation of code:

  • dataType will be “Size”, “Length”, or “Weight” based on which option is selected in the dropdown

Group the data by data category

Just below the dataType hook, paste the following code:

 const groupedData: Partial<PlotData>[] = [];
 for (let i = 0; i < count; i += 1) {
   const dataTypeVal = supportingData[i][dataType];
   const existingGroup = groupedData.find((gd) => gd.name === dataTypeVal);
   if (existingGroup) {
     (existingGroup.x as number[]).push(startingNumbers[i]);
     (existingGroup.y as number[]).push(randomNumbers[i]);
   } else {
     groupedData.push({
       x: [startingNumbers[i]],
       y: [randomNumbers[i]],
       name: dataTypeVal,
       mode: "markers",
       marker: {
         color: colorMap[dataTypeVal]
       }
     });
   }
 }
Then, assign the groupedData variable to Plot.data
<Plot
       data={groupedData}

Explanation of code:

  • We’re grouping and separating the data based on which dataType value it has and identifying which group the data belongs to based by assigning that dataType value to the “name” property.
  • We also pick the marker color by passing the dataType value to the colorMap we created previously.
  • As we iterate through the data, if we see that we have already created a group based on the dataType value, we can add additional points to that data object instead of creating a new one.

You should then be able to see the marker’s change color when you change the dataType!

Conclusion

Not only can you modify a marker’s color, you can also modify its size, opacity, and even gradient. See for yourself by looking at the Plotly.PlotMarker type.

Here is a finished sandbox: https://codesandbox.io/s/plotly-color-by-multi-category-b7zgo2?file=/src/App.tsx

Parts

Part 1 of 3: Controlling Plotly in React – Control the Mode Bar
Part 2 of 3: Controlling Plotly in React – Fully Custom Annotations
Part 3 of 3: Controlling Plotly in React – Adding Custom Color Markers by Category

About Intertech

Intertech is a Software Development Consulting Firm that provides single and multiple turnkey software development teams, available on your schedule and configured to achieve success as defined by your requirements independently or in co-development with your team. Intertech teams combine proven full-stack, DevOps, Agile-experienced lead consultants with Delivery Management, User Experience, Software Development, and QA experts in Business Process Automation (BPA), Microservices, Client- and Server-Side Web Frameworks of multiple technologies, Custom Portal and Dashboard development, Cloud Integration and Migration (Azure and AWS), and so much more. Each Intertech employee leads with the soft skills necessary to explain complex concepts to stakeholders and team members alike and makes your business more efficient, your data more valuable, and your team better. In addition, Intertech is a trusted partner of more than 4000 satisfied customers and has a 99.70% “would recommend” rating.