santilland / plotty Goto Github PK
View Code? Open in Web Editor NEWPlotting library experiments using WebGL and Canvas2D to apply color scale to a bufferarray object.
License: MIT License
Plotting library experiments using WebGL and Canvas2D to apply color scale to a bufferarray object.
License: MIT License
Version tested: v0.4.3
When I use the domain
property to target a subset of my data, the colour scale does not 'stretch' across the domain properly.
If I set domain: [1, 10]
and I render data that has values of 10
present, I would expect those values to be represented by the uppermost colour on the scale.
I've set up a simple repro here: https://gist.github.com/danwild/de5efaf725cad25b4e6f3c9ba32e702f
E.g. the below image contains data from [7, 10], with the viridis
scale I would expect cells with value of 10 to be bright yellow (not green)?
Hi, thanks for this library, it help me a lot.
there is just a liitle typo, thank you
yignbu --> ylgnbu
yiorrd --> ylorrd
yignbu: {
colors: ['#081d58','#253494','#225ea8','#1d91c0','#41b6c4','#7fcdbb','#c7e9b4','#edf8d9','#ffffd9'],
positions: [0,0.125,0.25,0.375,0.5,0.625,0.75,0.875,1]
}
yiorrd: {
colors: ['#800026','#bd0026','#e31a1c','#fc4e2a','#fd8d3c','#feb24c','#fed976','#ffeda0','#ffffcc'],
positions: [0,0.125,0.25,0.375,0.5,0.625,0.75,0.875,1]
},
I need to import but
import { plot } from 'plotty'
Show the error:
Uncaught SyntaxError: The requested module '/node_modules/.vite/deps/plotty.js?t=1696242010969&v=89c706aa' does not provide an export named 'default' (at App.vue:125:8)
Can support custom image location?eg: Ctx. putImageData (imageData, x, y);
Hello there,
I am using plotty to load raster(tiff) image on the map but I see that the image smoothing is always being true, do you know how can I make it false?
`let image = await this.fetchGeoTiffImage(cropPathObject)
let rasters = await image.readRasters()
let bbox = image.getBoundingBox()
let bitmapCanvas = this.refs.myCanvas
let band0 = rasters[0]
let band1 = rasters[1]
let bandF = new Float32Array(band0)
for (let i = 0; i < band0.length; i++) {
if (band1[i] < 75) {
bandF[i] = NaN
}
}
this.min = Math.min.apply(null, bandF.filter(x => !isNaN(x)))
this.max = Math.max.apply(null, bandF.filter(x => !isNaN(x)))
let plotLayer = new plotty.plot({
canvas: bitmapCanvas,
useWebGL: false,
data: this.state.bandFView ? bandF : band0,
width: image.getWidth(),
height: image.getHeight(),
domain: [this.min, this.max],
colorScale: 'viridis',
})
plotLayer.render()`
Hi
Does plotty work server side? when i do npm install plotty
- under my nodejs server directory and try to import plotty and run node, i get
/home/ubuntu/c/node_modules/plotty/src/plotty.js:11 import { colorscales } from './colorscales'; ^^^^^^
note: the reason i'm using plotty server side is because i was hoping to convert an 8 band GeoTiff onto a canvas in a simple way with simple RGB values, and then get the Buffer of the canvas to just store the image as a jpg/png buffer.
I'm trying to plot geotiff in open layer, Basically following this example: https://github.com/pbabik/webraster/blob/master/index.html
I'm doing the same think in ionic/angular latest version, unfortunately it's giving the following error.
here is the implementation
let the_canvas = this.document.createElement('canvas'); //create an offscreen canvas for rendering
this.renderer.appendChild(this.elementRef.nativeElement, the_canvas);
const plot = new plotty.plot({
canvas: the_canvas,
data: bands[0], width: image.getWidth(), height: image.getHeight(),
domain: [minValue, maxValue],
colorScale: 'earth',
clampLow: true,
clampHigh: true
});
plot.render();
Error
Uncaught TypeError: Cannot read properties of null (reading 'width')
at e.value (plotty.min.js:8:9685)
at ol-map.component.ts:229:12
at timer (zone.js:3128:1)
at _ZoneDelegate.push.23484._ZoneDelegate.invokeTask (zone.js:443:1)
at Zone.push.23484.Zone.runTask (zone.js:214:1)
at push.23484.ZoneTask.invokeTask (zone.js:525:1)
at ZoneTask.invoke (zone.js:514:1)
at data.args.<computed> (zone.js:3108:1)
I consoled the the_canvas
and it's there!
How is the 'atPoint' work,i don't understand the mean of the 'x,y' about .If or not the image or the geocoordinate?
I have a raster file that includes NaN values, but it returns false due to the fact that NaN !== Nan :(
plotty.js:
if (data[i] === this.noDataValue) {
alpha = 0;
}
Is it possible to add support for this?
I have multiple data layers https://developers.google.com/maps/documentation/solar/data-layers?hl=es-419 and I need to show one image superimposed on the other.
Hello, firstly thanks for a great little library much appreciated. At the moment I am trying to render a GeoTIFF on an OpenLayers 3 map with Plotty. Things are going great up until the point where I try and set the no data value (in this case to 0, represented by the dark blue in the image below). The whole layer simply disappears :(. No error messages are thrown in the console.
I am using this with GeoTiffs in the browser with Leaflet. I am wondering if there a way to smooth the hard -edges of the output data when applying the colorscales.
When zooming in. the blocks are definitely more defined and there is no real gradient between the colors
We do some of this with another effort and trying to find a way to get the same sort of gradiented look with a preset color palette
test
As far as I understand, if useWebGL = true
is set (which is the default), plotty tries to load a WebGL context. If this fails, a fallback to a normal 2d canvas should happen. But in certain cases, this does not work.
If your device supports WebGL, a call to getContext('[experimental-]webgl')
in create3DContext
succeeds. Then it is checked if the WebGL extension OES_texture_float
is available and only if this is true the rendering context is returned.
Problem is: after a successful call to getContext('webgl')
, you cannot make a subsequent getContext('2d')
call on the same canvas, since the latter will always return null
.
You can try this e.g. with
var canvas = document.createElement("canvas");
var ctx;
ctx = canvas.getContext('webgl');
console.log(ctx);
ctx = canvas.getContext('2d');
console.log(ctx);
So, in the fallback, the context is not properly initialized and the plotty object is not functional since it neither has a WebGL context nor a conventional 2d context.
I guess one would have to find a way of checking WebGL and OES_texture_float support without creating a rendering context. Or do the checks with a dummy canvas.
Hi @santilland, first of all, I have been using plotty for a couple of years and it is awesome so thank you. Recently I was trying to debug an issue where a color was present when I would not expect it.
To better understand how plotty is working I made a sandbox: https://codesandbox.io/s/plotty-testing-rz1f1
But it behaves strangely and I am hoping you can explain what is going on. Perhaps I am simply misunderstanding how colorscales in plotty work.
The demo displays a 10x10 set of data that counts from 1-100. I have overlayed numbers on top of the canvas (scaled up) to better illustrate the issue.
Are the highlighted numbers what you would expect given the data, domain, colors, and positions? Moving the sliders does not give me 1:1 color changes like I would expect. I am hoping you can shed some light onto what's going on.
I am processing geotiff images using the plotty library
In small size images with relatively small height and width - they all work perfectly (but slowly...)
In images with large size images with large height and width the browser throws a lot of warnings, sometimes crashes and of course does not display the layer
The warning is:
mapbox-gl.js:35 WebGL: INVALID_VALUE: bufferSubData: buffer overflow
mapbox-gl.js:35 WebGL: INVALID_OPERATION: bindBuffer: object does not belong to this context
WebGL: CONTEXT_LOST_WEBGL: loseContext: context lost
Hi,
I have a tif that I would like to use the 'rainbow' color scale with. The tif's "data" are pixels with integer values from 1 to 7. The tif's "nodata" pixels have a value of 127. When I use 'rainbow' like in the following, my tif contains greens and blues, but no reds or yellows:
rendererOptions = {
"renderer": L.LeafletGeotiff.plotty({
displayMin: 0,
displayMax: 10,
clampLow: true,
clampHigh: false,
domain: [1, 7],
colorScale: 'rainbow'
})
}
var geotiff_layer = L.leafletGeotiff(url, rendererOptions).addTo(map);
I tried creating my own color scale with rainbow colors as well. I saw different colors, but the colors were muted, almost as if there was a non-zero alpha. So red looked pink. Setting opacity and fillOpacity to 0.0 in the rendererOptions did not fix that problem:
plotty.addColorScale("mycolorscale", ["#bc0f0f", "#377eb8", "#4daf4a", "#984ea3", "#ff7f00", "#ffff33", "#a65628"], [0, 0.15, 0.3, 0.45, 0.6, 0.75, 1.0]);
What should I do to see the full range of rainbow colors in my tif using plotty?
Whether it is possible to support range filtering, for example, by adding a new parameter:
Now, nodatavalue only supports single value filtering. We can add a parameter to support passing an array [min, Max] to specify the range of displayed values
Shaders need to be changed:
precision mediump float;
uniform sampler2D u_textureData;
uniform sampler2D u_textureScale;
uniform vec2 u_textureSize;
uniform vec2 u_domain;
uniform float u_noDataValue;
uniform vec2 u_data_range;
uniform bool u_clampRange;
uniform bool u_clampLow;
uniform bool u_clampHigh;
varying vec2 v_texCoord;
void main() {
vec2 onePixel = vec2(1.0, 1.0) / u_textureSize;
float value = texture2D(u_textureData, v_texCoord)[0];
if (value == u_noDataValue)
gl_FragColor = vec4(0.0, 0, 0, 0.0);
else if (u_clampRange && (value < u_data_range[0] || value >= u_data_range[1]))
gl_FragColor = vec4(0.0, 0, 0, 0.0);
else if ((!u_clampLow && value < u_domain[0]) || (!u_clampHigh && value > u_domain[1]))
gl_FragColor = vec4(0, 0, 0, 0);
else {
float normalisedValue = (value - u_domain[0]) / (u_domain[1] - u_domain[0]);
gl_FragColor = texture2D(u_textureScale, vec2(normalisedValue, 0));
}
}
this.dataRange = [min, max];
const positionLocation = gl.getAttribLocation(program, 'a_position');
const domainLocation = gl.getUniformLocation(program, 'u_domain');
const resolutionLocation = gl.getUniformLocation(program, 'u_resolution');
const dataRange = gl.getUniformLocation(program, 'u_data_range');
const noDataValueLocation = gl.getUniformLocation(program, 'u_noDataValue');
const clampRangeLocation = gl.getUniformLocation(program, 'u_clampRange');
const clampLowLocation = gl.getUniformLocation(program, 'u_clampLow');
const clampHighLocation = gl.getUniformLocation(program, 'u_clampHigh');
const matrixLocation = gl.getUniformLocation(program, 'u_matrix');
gl.uniform2f(resolutionLocation, canvas.width, canvas.height);
gl.uniform2fv(domainLocation, this.domain);
gl.uniform2fv(dataRange, this.dataRange);
gl.uniform1i(clampRangeLocation, this.clampRange); // true or false
gl.uniform1i(clampLowLocation, this.clampLow);
gl.uniform1i(clampHighLocation, this.clampHigh);
gl.uniform1f(noDataValueLocation, this.noDataValue);
gl.uniformMatrix3fv(matrixLocation, false, this.matrix);
The result:
I'd like to create a color scale where the steps are geometrically increasing, e.g.:
[0, 1, 5, 10, 50, 100, 1000]
When I try this, the colors are not correct. For example, the color that shows for value 100 is close to the color for 1.
I have defined the following colorscale:
plotty.addColorscale("clouds_red", ["#ff000000", "#ff0000ff"], [0, 1]);
When useWebGL = false
, this behaves as expected:
For useWebGL = true
, intermediate values get interpolated to strange greyish tones:
This issue shows only for non-grey colorscales with transparency.
issue
I want to style my raster using exact color value, rather than blended color. For example if 3 is white and 4 is black a value of 3.92 and 3.35 would still be be white instead of grey.
In QGIS, I can use Discrete Interpolation instead of Linear Interpolation when applying the style. Here are the examples of both style:
How can I style my raster as in second image using Plotty?
It would be nice if the default value for the options was shown in the docs. It looks like you're using something to generate or edit the docs so I didn't think a PR was appropriate.
Option | Default |
---|---|
canvas |
document.createElement('canvas') |
data |
undefined |
width |
options.data[options.data.length - 2] * |
height |
options.data[options.data.length - 2] * |
datasets |
undefined |
colorScaleImage |
undefined |
colorScale |
'viridis' |
domain |
[0, 1] |
clampLow |
true |
clampHigh |
clampLow ** |
noDataValue |
undefined |
matrix |
[1, 0, 0, 0, 1, 0, 0, 0, 1 ] |
useWebGL |
true |
*When data
is defined.
**clampHigh
will default to the value of clampLow
Notes
useWebGL
isn't mentioned currently in the docs.If no WebGL is used, colorscales like the following, which use transparency, do not display correctly.
plotty.addColorScale("clouds", ["#00000000", "#000000ff"], [0, 1]);
I think this is because of this line in the render
method, where the value of the colorscale is not considered.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.