Skip to content

Commit

Permalink
Website | Gallery: Scatter Plot with Varied Shape
Browse files Browse the repository at this point in the history
  • Loading branch information
lee00678 committed Apr 26, 2024
1 parent 0999a98 commit d69ad9b
Show file tree
Hide file tree
Showing 14 changed files with 349 additions and 0 deletions.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions packages/shared/examples/examples-list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export const examples: ExampleCollection[] = [
examples: [
require('./basic-scatter-plot').default,
require('./sized-scatter-plot').default,
require('./shaped-scatter-plot').default,
],
},
{
Expand Down
107 changes: 107 additions & 0 deletions packages/shared/examples/shaped-scatter-plot/data.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
export type DataRecord = {
name: string;
owner: string;
trainedParam: number;
date: string;
};


export const categories = [
'Amazon',
'Anthropic',
'OpenAI',
'Google',
'Meta',
'Other',
]

export const shapes = [
'circle',
'cross',
'diamond',
'square',
'star',
'triangle',
]

export const sumCategories = (category: string): string => {
return categories.indexOf(category) === -1 ? 'Other' : category
}

export const data = [
{ name: 'Claude 3', owner: 'Anthropic', trainedParam: 2000, date: 'Mar-2024' },
{ name: 'Wu Dao 2.0', owner: 'Chinese', trainedParam: 1750, date: 'Jan-2021' },
{ name: 'Gemini Ultra', owner: 'Google', trainedParam: 1500, date: 'Dec-2023' },
{ name: 'Gemini Pro 1.5', owner: 'Google', trainedParam: 1500, date: 'Feb-2024' },
{ name: 'GLaM', owner: 'Google', trainedParam: 1200, date: 'Dec-2021' },
{ name: 'Inflection-202', owner: 'Inflection', trainedParam: 1200, date: 'Nov-2023' },
{ name: 'Inflection-202.5', owner: 'Inflection', trainedParam: 1200, date: 'Mar-2024' },
{ name: 'PanGu-Sigma', owner: 'Chinese', trainedParam: 1085, date: 'Mar-2023' },
{ name: 'GPT-4*', owner: 'OpenAI', trainedParam: 1000, date: 'Mar-2023' },
{ name: 'BingChat*', owner: 'Microsoft', trainedParam: 1000, date: 'Apr-2023' },
{ name: 'Ernie 4.0', owner: 'Chinese', trainedParam: 1000, date: 'Oct-2023' },
{ name: 'GPT-4 Turbo', owner: 'Open AI', trainedParam: 1000, date: 'Nov-2023' },
{ name: 'PaLM', owner: 'Google', trainedParam: 540, date: 'Apr-2022' },
{ name: 'Minerva', owner: 'Google', trainedParam: 540, date: 'Jun-2022' },
{ name: 'PaLM2', owner: 'Google', trainedParam: 540, date: 'May-2023' },
{ name: 'Mistral-large', owner: 'Mistral AI', trainedParam: 540, date: 'Feb-2024' },
{ name: 'Megatron-Turing NLG', owner: 'Meta', trainedParam: 530, date: 'Oct-2021' },
{ name: 'MT-NLG', owner: 'Microsoft', trainedParam: 530, date: 'Oct-2021' },
{ name: '530B', owner: 'Chinese', trainedParam: 530, date: 'Feb-2024' },
{ name: 'BERT-480', owner: 'Google', trainedParam: 480, date: 'Nov-2021' },
{ name: 'Titan', owner: 'Amazon', trainedParam: 350, date: 'Apr-2023' },
{ name: 'Grok 1', owner: 'Twitter', trainedParam: 314, date: 'Nov-2023' },
{ name: 'Exaone', owner: 'LG', trainedParam: 300, date: 'Dec-2022' },
{ name: 'Gopher', owner: 'Google', trainedParam: 280, date: 'Dec-2021' },
{ name: 'Ernie 3.0 Titan', owner: 'Chinese', trainedParam: 260, date: 'Dec-2021' },
{ name: 'PanGu-Alpha', owner: 'Huawei', trainedParam: 200, date: 'Apr-2021' },
{ name: 'BERT-20200', owner: 'Google', trainedParam: 200, date: 'Nov-2021' },
{ name: 'Luminous', owner: 'Aleph Alpha', trainedParam: 200, date: 'Nov-2021' },
{ name: 'Ernie Bot', owner: 'Chinese', trainedParam: 200, date: 'Dec-2021' },
{ name: 'Jurassic-202*', owner: 'AI21', trainedParam: 200, date: 'Mar-2023' },
{ name: 'SenseChat', owner: 'SenseTime', trainedParam: 200, date: 'Apr-2023' },
{ name: 'Tongyi Qianwen', owner: 'Chinese', trainedParam: 200, date: 'Apr-2023' },
{ name: 'Ernie Bot 3.5', owner: 'Chinese', trainedParam: 200, date: 'Jul-2023' },
{ name: 'GLM-4', owner: 'Zhipu AI', trainedParam: 200, date: 'Jan-2024' },
{ name: 'Xinghuo 3.5', owner: 'Chinese', trainedParam: 200, date: 'Jan-2024' },
{ name: 'Falcon 180B', owner: 'TII', trainedParam: 180, date: 'Sep-2023' },
{ name: 'Q', owner: 'Amazon', trainedParam: 180, date: 'Dec-2023' },
{ name: 'Mistral-medium', owner: 'Mistral AI', trainedParam: 180, date: 'Dec-2023' },
{ name: 'Jurassic-1', owner: 'AI21', trainedParam: '178', date: 'Aug-2021' },
{ name: 'GPT-3', owner: 'OpenAI', trainedParam: 175, date: 'May-2020' },
{ name: 'OPT-IML', owner: 'Meta', trainedParam: 175, date: 'May-2022' },
{ name: 'BLOOM', owner: 'BigScience', trainedParam: 175, date: 'Jul-2022' },
{ name: 'BlenderBot3', owner: 'Meta', trainedParam: 175, date: 'Aug-2022' },
{ name: 'GPT 3.5', owner: 'OpenAI', trainedParam: 175, date: 'Dec-2022' },
{ name: 'WebGPT', owner: 'Microsoft', trainedParam: 175, date: 'Jan-2023' },
{ name: '175B', owner: 'Chinese', trainedParam: 175, date: 'Feb-2024' },
{ name: 'LaMDA', owner: 'Google', trainedParam: 137, date: 'Jun-2021' },
{ name: 'FLAN', owner: 'Google', trainedParam: 137, date: 'Sep-2021' },
{ name: 'GLM-130B', owner: 'Chinese', trainedParam: 130, date: 'Aug-2022' },
{ name: 'Claude 2.1', owner: 'Anthropic', trainedParam: 130, date: 'Nov-2023' },
{ name: 'Galactica', owner: 'Meta', trainedParam: 120, date: 'Nov-2022' },
{ name: 'Fuyu-heavy', owner: 'Adept', trainedParam: 120, date: 'Jan-2024' },
{ name: 'Yuan 2.0', owner: 'IEIT', trainedParam: 102, date: 'Nov-2023' },
{ name: 'YaLM 100B', owner: 'Yandex', trainedParam: 100, date: 'Jun-2022' },
{ name: 'IDEFICS', owner: 'Independent', trainedParam: 80, date: 'Aug-2023' },
{ name: 'Qwen 1.5', owner: 'Chinese', trainedParam: 72, date: 'Feb-2024' },
{ name: 'Chinchilla', owner: 'DeepMind', trainedParam: 70, date: 'Mar-2022' },
{ name: 'Sparrow', owner: 'Google', trainedParam: 70, date: 'Sep-2022' },
{ name: 'Luminous Supreme', owner: 'Aleph Alpha', trainedParam: 70, date: 'Feb-2023' },
{ name: 'LLaMa2', owner: 'Facebook', trainedParam: 70, date: 'Jul-2023' },
{ name: 'MEDITRON', owner: 'EPFL', trainedParam: 70, date: 'Nov-2023' },
{ name: 'pplx-70b', owner: 'Perplexity', trainedParam: 70, date: 'Nov-2023' },
{ name: 'DeepSeek', owner: 'Wenge', trainedParam: 67, date: 'Jan-2024' },
{ name: 'LLaMa', owner: 'Meta', trainedParam: 65, date: 'Feb-2023' },
{ name: 'StableLM', owner: 'Stability AI', trainedParam: 65, date: 'Apr-2023' },
{ name: 'Vicuna-13B', owner: 'Vicuna Team', trainedParam: 65, date: 'Mar-2023' },
{ name: 'NLLB-20200', owner: 'Meta', trainedParam: 54.5, date: 'Jul-2022' },
{ name: 'xlarge', owner: 'Cohere', trainedParam: 52.4, date: 'Sep-2021' },
{ name: 'RL-CAI', owner: 'Anthropic', trainedParam: 52, date: 'Dec-2022' },
{ name: 'Claude', owner: 'Anthropic', trainedParam: 52, date: 'Jan-2023' },
{ name: 'Claude 2', owner: 'Anthropic', trainedParam: 52, date: 'Jul-2023' },
{ name: 'Claude Instant', owner: 'Anthropic', trainedParam: 52, date: 'Aug-2023' },
{ name: 'BloombergGPT', owner: 'Bloomberg', trainedParam: 50, date: 'Mar-2023' },
]


33 changes: 33 additions & 0 deletions packages/shared/examples/shaped-scatter-plot/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/* eslint-disable import/no-unresolved, import/no-webpack-loader-syntax, @typescript-eslint/no-var-requires */
import React from 'react'
import type { Example } from '../types'

const pathname = 'shaped-scatter-plot'
const example: Example = {
component: () => {
// eslint-disable-next-line @typescript-eslint/naming-convention
const Component = require(`./${pathname}.tsx`).default
return <Component />
},
pathname,
title: 'Scatter Plot with Varied Shape',
description: <div>
Data from <a href="https://informationisbeautiful.net/visualizations/the-rise-of-generative-ai-large-language-models-llms-like-chatgpt/" target="_blank">
information is beautiful
</a> (source: <em>The Rise and Rise of A.I.</em>)
</div>,
codeReact: require(`!!raw-loader!./${pathname}.tsx`).default,
codeTs: require(`!!raw-loader!./${pathname}.ts`).default,
codeAngular: {
html: require(`!!raw-loader!./${pathname}.component.html`).default,
component: require(`!!raw-loader!./${pathname}.component.ts`).default,
module: require(`!!raw-loader!./${pathname}.module.ts`).default,
},
codeSvelte: require(`!!raw-loader!./${pathname}.svelte`).default,
codeVue: require(`!!raw-loader!./${pathname}.vue`).default,
data: require('!!raw-loader!./data').default,
preview: require(`../_previews/${pathname}.png`).default,
previewDark: require(`../_previews/${pathname}-dark.png`).default,
}

export default example
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<h2>The Rise and Rise of A.I. Large Language Models</h2>
<vis-bullet-legend [items]="legendItems"></vis-bullet-legend>
<vis-xy-container [data]="data" [height]="600">
<vis-scatter
[x]="getX"
[y]="getY"
[color]="getColor"
[size]="15"
[shape]="getShape"
[label]="getLabel"
cursor="pointer"
></vis-scatter>
<vis-axis type="x" label="Date Released" [tickFormat]="xTicks"></vis-axis>
<vis-axis type="y" label="Billion Parameters"></vis-axis>
<vis-tooltip [triggers]="tooltipTriggers"></vis-tooltip>
</vis-xy-container>
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { Component } from '@angular/core'
import { Scale, Scatter, StringAccessor, colors } from '@unovis/ts'
import { data, DataRecord, shapes, categories, sumCategories } from './data'

const shapeScale = Scale.scaleOrdinal(shapes).domain(categories)
const colorScale = Scale.scaleOrdinal(colors).domain(categories)

@Component({
selector: 'shaped-scatter-plot',
templateUrl: './shaped-scatter-plot.component.html',
})
export class ShapedScatterPlotComponent {
data = data

getX = (d: DataRecord): number => +(new Date(d.date))
getY = (d: DataRecord): number => d.trainedParam
getColor = (d: DataRecord): string => colorScale(sumCategories(d.owner))
getShape = (d: DataRecord): string => shapeScale(sumCategories(d.owner))
getLabel = (d: DataRecord): string => d.name

legendItems = categories.map(v => ({ name: v, color: colorScale(v) }))
tooltipTriggers = {
[Scatter.selectors.point]: (d: DataRecord): string => `
<strong>name</strong>: ${d.name} <br>
<strong>owner</strong>: ${d.owner} <br>
<strong>bn parameters</strong>: ${d.trainedParam}`,
}

xTicks = Intl.DateTimeFormat('en', { month: 'long', year: 'numeric' }).format
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { NgModule } from '@angular/core'
import { VisXYContainerModule, VisScatterModule, VisAxisModule, VisTooltipModule, VisBulletLegendModule } from '@unovis/angular'

import { ShapedScatterPlotComponent } from './shaped-scatter-plot.component'

@NgModule({
imports: [VisXYContainerModule, VisScatterModule, VisAxisModule, VisTooltipModule, VisBulletLegendModule],
declarations: [ShapedScatterPlotComponent],
exports: [ShapedScatterPlotComponent],
})
export class ShapedScatterPlotModule { }
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<script lang='ts'>
import { Position, Scale, Scatter, colors } from '@unovis/ts'
import { VisXYContainer, VisScatter, VisAxis, VisTooltip, VisBulletLegend } from '@unovis/svelte'
import { data, DataRecord, shapes, categories, sumCategories } from './data'
const shapeScale = Scale.scaleOrdinal(shapes).domain(categories)
const colorScale = Scale.scaleOrdinal(colors).domain(categories)
// scatter props
const x = (d: DataRecord) => +(new Date(d.date))
const y = (d: DataRecord) => d.trainedParam
const color = (d: DataRecord) => colorScale(sumCategories(d.owner))
const shape = (d: DataRecord) => shapeScale(sumCategories(d.owner))
const label = (d: DataRecord) => d.name
const legendItems = categories.map(v => ({ name: v, shape: shapeScale(v) }))
const triggers = {
[Scatter.selectors.point]: (d: DataRecord) => `
<strong>name</strong>: ${d.name} <br>
<strong>owner</strong>: ${d.owner} <br>
<strong>bn parameters</strong>: ${d.trainedParam}`,
}
</script>

<h2>The Rise and Rise of A.I. Large Language Models</h2>
<VisBulletLegend items={legendItems}/>
<VisXYContainer {data} height={600} scaleByDomain={true}>
<VisScatter {x} {y} {color} {label} {shape} size={15} cursor='pointer'/>
<VisAxis type='x' label='Date Released' tickFormat={Intl.DateTimeFormat('en', { month: 'long', year: 'numeric' }).format}/>
<VisAxis excludeFromDomainCalculation type='y' label='Billion Parameters' tickPadding={0}/>
<VisTooltip {triggers}/>
</VisXYContainer>
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { Axis, BulletLegend, Position, Scale, Scatter, Tooltip, XYContainer, colors } from '@unovis/ts'
import { data, DataRecord, shapes, categories, sumCategories } from './data'

const shapeScale = Scale.scaleOrdinal(shapes).domain(categories)
const colorScale = Scale.scaleOrdinal(colors).domain(categories)
const container = document.getElementById('vis-container')

const title = document.createElement('h2')
title.innerText = 'The Rise and Rise of A.I. Large Language Models'
container.append(title)

const legend = new BulletLegend(container, {
items: categories.map(v => ({ name: v, shape: shapeScale(v) })),
})

const scatter = new Scatter<DataRecord>({
x: (d: DataRecord) => +(new Date(d.date)),
y: (d: DataRecord) => d.trainedParam,
color: (d: DataRecord) => colorScale(sumCategories(d.owner)),
shape: (d: DataRecord) => shapeScale(sumCategories(d.owner)),
size: 15,
label: (d: DataRecord) => d.name,
cursor: 'pointer',
})

const chart = new XYContainer(container, {
height: 600,
components: [scatter],
tooltip: new Tooltip({
triggers: {
[Scatter.selectors.point]: (d: DataRecord) => `
<strong>name</strong>: ${d.name} <br>
<strong>owner</strong>: ${d.owner} <br>
<strong>bn parameters</strong>: ${d.trainedParam}`,
},
}),
xAxis: new Axis({
label: 'Date Released',
tickFormat: Intl.DateTimeFormat('en', { month: 'long', year: 'numeric' }).format,
tickPadding: 0,
}),
yAxis: new Axis({ label: 'Billion Parameters', tickPadding: 0 }),
}, data)
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import React, { useCallback } from 'react'
import { Position, Scale, Scatter, colors } from '@unovis/ts'
import { VisAxis, VisBulletLegend, VisScatter, VisTooltip, VisXYContainer } from '@unovis/react'
import { data, DataRecord, shapes, categories, sumCategories } from './data'

const shapeScale = Scale.scaleOrdinal(shapes).domain(categories)
const colorScale = Scale.scaleOrdinal(colors).domain(categories)

export default function ShapedScatterPlot (): JSX.Element {
const legendItems = categories.map(v => ({ name: v, shape: shapeScale(v) }))
const tooltipTriggers = {
[Scatter.selectors.point]: (d: DataRecord) => `
<strong>name</strong>: ${d.name} <br>
<strong>owner</strong>: ${d.owner} <br>
<strong>bn parameters</strong>: ${d.trainedParam}`,
}
return (
<>
<h2>The Rise and Rise of A.I. Large Language Models</h2>
<VisBulletLegend items={legendItems}/>
<VisXYContainer data={data} height={'60vh'} scaleByDomain={true}>
<VisScatter
x={useCallback((d: DataRecord) => +(new Date(d.date)), [])}
y={useCallback((d: DataRecord) => d.trainedParam, [])}
shape={useCallback((d: DataRecord) => shapeScale(sumCategories(d.owner)), [])}
size={15}
label={useCallback((d: DataRecord) => d.name, [])}
labelHideOverlapping={true}
cursor='pointer'
color={useCallback((d: DataRecord) => colorScale(sumCategories(d.owner)), [])}
/>
<VisAxis type='x' label='Date Released'
tickFormat={Intl.DateTimeFormat('en', { month: 'long', year: 'numeric' }).format}/>
<VisAxis excludeFromDomainCalculation type='y' label='Billion Parameters' tickPadding={0}/>
<VisTooltip triggers={tooltipTriggers}/>
</VisXYContainer>
</>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<script setup lang="ts">
import { Position, Scale, Scatter, colors } from '@unovis/ts'
import { VisXYContainer, VisScatter, VisAxis, VisTooltip, VisBulletLegend } from '@unovis/vue'
import { data, DataRecord, shapes, categories, sumCategories } from './data'
const shapeScale = Scale.scaleOrdinal(shapes).domain(categories)
const colorScale = Scale.scaleOrdinal(colors).domain(categories)
// scatter props
const x = (d: DataRecord) => +(new Date(d.date))
const y = (d: DataRecord) => d.trainedParam
const color = (d: DataRecord) => colorScale(sumCategories(d.owner))
const shape = (d: DataRecord) => shapeScale(sumCategories(d.owner))
const label = (d: DataRecord) => d.name
const legendItems = categories.map(v => ({ name: v, shape: shapeScale(v) }))
const triggers = {
[Scatter.selectors.point]: (d: DataRecord) => `
<strong>name</strong>: ${d.name} <br>
<strong>owner</strong>: ${d.owner} <br>
<strong>bn parameters</strong>: ${d.trainedParam}`,
}
</script>

<template>
<h2>The Rise and Rise of A.I. Large Language Models</h2>
<VisBulletLegend :items="legendItems" />
<VisXYContainer :data="data" :height="600" :scaleByDomain="true">
<VisScatter :x="x" :y="y" :color="color" :shape="shape" :label="label"
cursor="pointer" />
<VisAxis type="x" label="Date Released" :tickFormat="Intl.DateTimeFormat('en', {month: 'long', year: 'numeric',}).format" />
<VisAxis excludeFromDomainCalculation type="y" label="Billion Parameters" :tickPadding="0" />
<VisTooltip :triggers="triggers" />
</VisXYContainer>
</template>
1 change: 1 addition & 0 deletions packages/svelte/src-demo/svelte-gallery.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
() => import('@unovis/shared/examples/hierarchical-chord-diagram/hierarchical-chord-diagram.svelte'),
() => import('@unovis/shared/examples/sunburst-nested-donut/sunburst-nested-donut.svelte'),
() => import('@unovis/shared/examples/basic-donut-chart/basic-donut-chart.svelte'),
() => import('@unovis/shared/examples/shaped-scatter-plot/shaped-scatter-plot.svelte'),
]
</script>

Expand Down
1 change: 1 addition & 0 deletions packages/vue/src-demo/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ const imports = [
defineAsyncComponent(() => import('@unovis/shared/examples/hierarchical-chord-diagram/hierarchical-chord-diagram.vue')),
defineAsyncComponent(() => import('@unovis/shared/examples/sunburst-nested-donut/sunburst-nested-donut.vue')),
defineAsyncComponent(() => import('@unovis/shared/examples/basic-donut-chart/basic-donut-chart.vue')),
defineAsyncComponent(() => import('@unovis/shared/examples/shaped-scatter-plot/shaped-scatter-plot.vue')),
]
</script>

Expand Down

0 comments on commit d69ad9b

Please sign in to comment.