matplotlib - show image color in hex format - matplotlib

I would like imshow display current image pixel value in hex format, by default it display pixel with decimal format.
for example, red color will be displayed as (255,0,0), I would like it to be (FF,00,00).
#!/usr/bin/env python3
import matplotlib.pyplot as plt
import matplotlib.image as image
import matplotlib.patches as patches
import matplotlib
import cv2
matplotlib.use('tkagg')
img = cv2.imread("input.png",cv2.IMREAD_UNCHANGED)# cv2.IMREAD_UNCHANGED load alpha channel
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
fig,ax =plt.subplots(1,figsize=(15,15))
ax.imshow(img)
fig.tight_layout()
plt.show()

You could connect a function the motion_notify_event and update the toolbar. Here is a standalone example:
import matplotlib.pyplot as plt
import matplotlib.cbook as cbook
import matplotlib
def show_hex_coords(event):
text = ''
rgb = img_plot.get_cursor_data(event)
if rgb is not None:
r, g, b = rgb
text = f'x={event.xdata:.0f} y={event.ydata:.0f}\n{r:02X} {g:02X} {b:02X}'
# print( f'#{r:02X}{g:02X}{b:02X}')
fig.canvas.toolbar.set_message(text)
matplotlib.use('tkagg')
with cbook.get_sample_data('grace_hopper.jpg') as image_file:
img = plt.imread(image_file)
fig, ax = plt.subplots(1, figsize=(6, 6))
img_plot = ax.imshow(img)
fig.canvas.mpl_connect("motion_notify_event", show_hex_coords)
plt.show()

Related

Is it possible to achieve a continuous color gradient with surface plot using matplotlib?

I am trying to visualise the pixel intensity of a photo by plotting a 3D graph. In the code below, lab is an image I want to analyse. The code will look at the pixel intensity of every pixels in the image and plot a graph, where the height denotes the pixel intensity.
Here is a portion of my code:
import cv2
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm
from skimage import io, color
import glob
from PIL import Image
plt.figure(dpi=1200)
ax = plt.axes(projection='3d')
y = range(lab.shape[0])
x = range(lab.shape[1])
X, Y = np.meshgrid(x, y)
ax.view_init(elev=60., azim=60)
thickness = ax.plot_surface(
X,
Y,
lab[:, :, 0], # change value here to adjust the height
cmap=cm.coolwarm,
antialiased=False)
# Add a color bar which maps values to colors.
fig.colorbar(thickness, shrink=0.5, aspect=5)
It outputs:
As you can see, the colour gradient is not continuous despite the graph having many fine details and slight fluctuations in height which is not represented by the color map.
Is it possible to achieve a continuous color gradient with surface plot using matplotlib like the image below?
Thank you.
You can use the colormap hsv to get the same result.
import cv2
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm
from skimage import io, color
import glob
from PIL import Image
lab = cv2.imread('Lenna.png')
lab = cv2.cvtColor(lab, cv2.COLOR_BGR2LAB)
fig = plt.figure()
ax = plt.axes(projection='3d')
y = range(lab.shape[0])
x = range(lab.shape[1])
X, Y = np.meshgrid(x, y)
ax.view_init(elev=60., azim=60)
thickness = ax.plot_surface(
X,
Y,
lab[:, :, 0], # change value here to adjust the height
cmap=plt.get_cmap('hsv'),
antialiased=False)
# Add a color bar which maps values to colors.
fig.colorbar(thickness, shrink=0.5, aspect=5)
plt.show()
output :
Take a look at the documentation for more colormaps.

plotting a svg or pdf into matplotlib

I have the same file saved both as .pdf and as .svg
I'd like to insert the file in a regular matplotlib plot.
How can I do that?
import matplotlib.pyplot as plt
pdfFile = open('file.pdf')
svgFile = open('file.svg')
fig,ax = plt.subplots(1,2)
ax[0].imshow(pdfFile)
ax[1].imshoe(svgFile)
plt.show()
Alternately I've tried with
from svglib.svglib
import svg2rlg
from reportlab.graphics import renderPDF, renderPM >>> >>> drawing = svg2rlg("file.svg") >>> renderPDF.drawToFile(drawing, "file.pdf")

How to resave image without borders in matplotlib

I am just want to show and then save the same image on plot but got borders.
import numpy as np
import skimage.io
import matplotlib
import matplotlib.pyplot as plt
fileName = "1.jpg"
image=mpimg.imread(fileName)
height, width = image.shape[:2]
my_dpi = 96 / 2
fg, ax = plt.subplots(1, figsize=(1080/my_dpi, 1920/my_dpi), dpi=my_dpi)
ax.set_ylim(height, 0)
ax.set_xlim(0, width)
ax.axis('off')
ax.imshow(image.astype(np.uint8))
plt.savefig("res.png")
Source image:
Result image after resaving:
How to remove the borders and make the result image be the same as original without borders?

Matplotlib-Basemap: how to hide the text out of axes?

I want to hide the text outside of the axes, and show only what is inside. I have tried to do it with zorder, but just the text in the axes are gone instead!
import pandas as pd
import numpy as np
import numpy.ma as ma
import matplotlib.pyplot as plt
from matplotlib import cm as CM
from mpl_toolkits.basemap import Basemap
from matplotlib.patches import Polygon
names=['stat','latd', 'longd', 'AQI', 'Grade', 'PM25', 'PM10', 'CO', 'NO2', 'O3', 'O3_8h', 'SO2']
cities=pd.read_table('2013061713.000',sep='\s+',names=names,skiprows=[0],na_values=[9999])
namesa=['LOC1','LOC2','LOC3','LOC4','LOC5','LOC6','LOC7','LOC8']
LOC=pd.read_table('loc/location_use13-06-17.txt',sep='\s+',names=namesa,na_values=[9999])
# Extract the data we're interested in
lat = cities['latd'].values
lon = cities['longd'].values
pm25 = cities['PM25'].values
aqi = cities['AQI'].values
pm25_max=np.nanmax(pm25)
pm25_min=np.nanmin(pm25)
latmax=LOC.iloc[:,:4].max().max()
latmin=LOC.iloc[:,:4].min().min()
lonmax=LOC.iloc[:,4:8].max().max()
lonmin=LOC.iloc[:,4:8].min().min()
llcrnrlon=lonmin-0.5
llcrnrlat=latmin-0.5
urcrnrlon=lonmax+0.5
urcrnrlat=latmax+0.5
fig = plt.figure(figsize=(8, 8))
m = Basemap(llcrnrlon=llcrnrlon,llcrnrlat=llcrnrlat,urcrnrlon=urcrnrlon,urcrnrlat=urcrnrlat, epsg=4269)
m.shadedrelief()
m.drawparallels(np.arange(20.,40,2.5),linewidth=1, dashes=[4, 2], labels=[1,0,0,0], color= 'gray',zorder=0, fontsize=10)
m.drawmeridians(np.arange(100.,125.,2.),linewidth=1, dashes=[4, 2], labels=[0,0,0,1], color= 'gray',zorder=0, fontsize=10)
y_offset = 0.05
rotation = 30
x, y = m(lon, lat)
for i,j,k,a in zip(x[::2],y[::2],pm25[::2],aqi[::2]):
m.scatter(i, j,c=k, s=a, cmap=CM.get_cmap('tab20b',20), alpha=0.5)
plt.text(i, j+y_offset, k,rotation=rotation,fontsize=6,color='w')
for i,j,k,a in zip(x[1::2],y[1::2],pm25[1::2],aqi[1::2]):
m.scatter(i, j,c=k, s=a, cmap=CM.get_cmap('tab20b',20), alpha=0.5)
plt.text(i, j-y_offset, k,rotation=rotation,fontsize=6,color='b')
plt.savefig('PM25_showtext130617.png',dpi=600)
plt.show()
Here is the image with all the text, the text ouside the axes should be hidden:
And this is my current output, when I use the zorder, which is the opposite of what I try to achieve:
plt.text(i, j+y_offset, k,rotation=rotation,fontsize=6,color='w',zorder=-1000)

Hue Saturation Intensity Histogram

I am using Debian Linux Siduction. I have an image in jpg format which I can read and convert to arrray. But I want to convert the image from RGB color model to HSI color model and then plot a histogram for the saturation and intesity parameters of the HSI image. I have tried to plot the intesity part but I'm not sure about the accuracy of my results. I have included the code.
import scipy
from scipy import ndimage
import matplotlib.pyplot as plt
import matplotlib.colors as colors
import numpy as np
from scipy import misc
import scipy.misc
img = scipy.misc.imread("/home/subhradeep/Desktop/ref.jpg")
array=np.asarray(img)
arr=(array.astype(float))/255.0
img_hsv = colors.rgb_to_hsv(arr[...,:3])
lu1=img_hsv[...,0].flatten()
plt.subplot(1,3,1)
plt.hist(lu1*360,bins=360,range=(0.0,360.0),histtype='stepfilled', color='r', label='Hue')
plt.title("Hue")
plt.xlabel("Value")
plt.ylabel("Frequency")
plt.legend()
lu2=img_hsv[...,1].flatten()
plt.subplot(1,3,2)
plt.hist(lu2,bins=100,range=(0.0,1.0),histtype='stepfilled', color='g', label='Saturation')
plt.title("Saturation")
plt.xlabel("Value")
plt.ylabel("Frequency")
plt.legend()
lu3=img_hsv[...,2].flatten()
plt.subplot(1,3,3)
plt.hist(lu3*255,bins=256,range=(0.0,255.0),histtype='stepfilled', color='b', label='Intesity')
plt.title("Intensity")
plt.xlabel("Value")
plt.ylabel("Frequency")
plt.legend()
plt.show()
here is the histogram i have got by taking bin size 100 but I'm not sure what should be the appropriate size for my data
img = scipy.misc.imread("/home/subhradeep/Desktop/test.jpg")
array=np.asarray(img)
# convert, but this is buggy
im_hsv = matplotlib.colors.rgb_to_hsv(array[...,:3])
# pull out just the s channel
lu=img_hsv[...,1].flatten()
plt.hist(lu,256)
plt.show()