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
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";
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");
// <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
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]
}
});
}
}
<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 Black Slate
Black Slate 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. Black Slate 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 Black Slate 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, Black Slate is a trusted partner of more than 4000 satisfied customers and has a 99.70% “would recommend” rating.