Giter Site home page Giter Site logo

santilland / plotty Goto Github PK

View Code? Open in Web Editor NEW
160.0 7.0 38.0 2.89 MB

Plotting library experiments using WebGL and Canvas2D to apply color scale to a bufferarray object.

License: MIT License

JavaScript 78.67% HTML 16.89% CSS 1.03% PEG.js 3.41%

plotty's Issues

Colorscales with transparency do not work without WebGL

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.

Using NaN as noDataValue

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?

ctx.imageSmoothingEnabled is always true

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()`

Question: If there a way to get better color gradients between pixels?

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.
image

When zooming in. the blocks are definitely more defined and there is no real gradient between the colors
image

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
image

Discrete Interpolation for Color Scaling

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:

Linear Interpolation
image

Discrete Interpolation
image

How can I style my raster as in second image using Plotty?

WebGL crash during render large scale images

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

Option defaults in docs

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.
  • I do not understand what the defaults for width and height do.

color scale with arbitrary step sizes

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.

How to import plotty into node project

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)

ionic/angular rendering error

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!

server side?

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.

help using color scale

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?

Colorscales name error

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]
},

Color-stop edge behavior unclear

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.

image

Colour does not correctly scale to domain

Version tested: v0.4.3

Observed behaviour

When I use the domain property to target a subset of my data, the colour scale does not 'stretch' across the domain properly.

Expected

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)?

plotty-example

Initialization fails for devices that support WebGL but do not support OES_texture_float

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.

How is the 'atPoint' work?

How is the 'atPoint' work,i don't understand the mean of the 'x,y' about .If or not the image or the geocoordinate?

Interpolation of some colorscales with transparency fails if using WebGL

I have defined the following colorscale:

plotty.addColorscale("clouds_red", ["#ff000000", "#ff0000ff"], [0, 1]);

When useWebGL = false, this behaves as expected:
plotty_webgl_false

For useWebGL = true, intermediate values get interpolated to strange greyish tones:
plotty_webgl_true

This issue shows only for non-grey colorscales with transparency.

Setting NoData to 0 causes entire raster not to render

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.

blue

Can we limit the range of values?

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));
    }
}
  • The code needs to be modified:
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:

image

image

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.