import matplotlib.pyplot as plt
from matplotlib.widgets import Slider
import numpy as np
from PIL import Image
import requests
from io import BytesIO
img_src = 'https://unsplash.it/500/300'
response = requests.get(img_src)
img = Image.open(BytesIO(response.content))
img = np.asarray(img.convert('L'))
fig,ax = plt.subplots()
zlims = (np.percentile(img[:, :], 0), np.percentile(img[:, :], 100 - 0))
im = ax.imshow(img, aspect='auto',vmin=zlims[0], vmax=zlims[1])
threshold = 0.
axthreshold = plt.axes([0.2, 0.01, 0.65, 0.03])
sthreshold = Slider(axthreshold, 'clip', -.1, 15.,
valinit=threshold, valstep=None)
def update(val):
ax.clear()
zlims = (np.percentile(img[:, :], .1+val), np.percentile(img[:, :], 100 - (.1+val)))
print(zlims[0],zlims[1])
ax.imshow(img, aspect='auto',vmin=zlims[0], vmax=zlims[1])
fig.canvas.draw_idle()
sthreshold.on_changed(update)
update(threshold)
this creates a image where you can limit what range the colormap covers with a slider. As "clip" increases the color map variety lessens.
Im am pretty familiar with flask. Is there any way to implement something like this into flask? I would prefer matplotlib but I'm ok with trying anything.
Thanks!
--Update--- I realized that I don't want to refresh the page every time the picture is adjusted. I tried plotly javascript approach. I was happy until I realized the res is too low.
html:
<!doctype html>
<html class="no-js" lang="en">
<head>
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script src="https://cdn.plot.ly/plotly-2.11.1.min.js"></script>
<style>
.container {
display: flex;
align-items: center;
justify-content: center;
}
</style>
</head>
<body>
<div class="container" id="myDiv"></div>
<div class="container">
<input style="width:50%" id="slide" type="range" min="0" max="5" step="0.025" value=".1" name="name_of_slider">
</div>
<div class="container" id="sliderAmount"></div>
<script>
const z1 = JSON.parse('{{ Lsort | tojson }}');
const IMG = JSON.parse('{{ IMG | tojson }}');
var size = z1.length
var qlower = z1[Math.ceil(size * .1 / 100) - 1]
var qupper = z1[Math.ceil(size * (100-.1) / 100) - 1]
var data = [
{
z: IMG,
type: 'heatmap',
colorscale: 'Viridis',
zauto: false,
zmax: qupper,
zmin: qlower,
}
];
var layout = {
autosize: false,
width: 1000,
height: 600,
};
Plotly.newPlot('myDiv', data, layout);
var slide = document.getElementById('slide'),
sliderDiv = document.getElementById("sliderAmount");
slide.onchange = function() {
sliderDiv.innerHTML = this.value;
var perc = this.value
var qlower = z1[Math.ceil(size * perc / 100) - 1]
var qupper = z1[Math.ceil(size * (100-perc) / 100) - 1]
var data = [
{
z: IMG,
type: 'heatmap',
colorscale: 'Viridis',
zauto: false,
zmax: qupper,
zmin: qlower,
}
];
var layout = {
autosize: false,
width: 1000,
height: 600,
};
Plotly.newPlot('myDiv', data, layout);
}
</script>
</body>
</html>
python:
from PIL import Image
import requests
from io import BytesIO
img_src = 'https://unsplash.it/500/300'
response = requests.get(img_src)
imgarray = Image.open(BytesIO(response.content))
imgarray = np.asarray(imgarray.convert('L'))
n = np.sort(imgarray.ravel()).tolist()
imgarray2D = np.flip(imgarray,axis=0)
imgarray2D = imgarray2D.tolist()
app = Flask(__name__)
@app.route('/', methods=['GET', 'POST'])
def main():
return render_template('clip.html',Lsort = n,IMG=imgarray2D)
if __name__ == '__main__':
app.run()