I need a function in matplotlib to extract the color or color value of a point if the coordinates are provided. What I intend to do is:
import matplotlib.pyplot as plt
x=int(input("x coordinate: "))
y=int(input("y coordinate: "))
plt.plot(x,y,color='blue')
c=plt.<extract_color_function>(x,y) #this must store the color(as a String)/colour value(as a tuple)
if c=='black':
<do something>
else:
<do something>
Here, <extract_color_function> is what I need. Is there something like this in the pyplot module? If not, can you suggest some alternative?
CodePudding user response:
Since you want to do color detection on your plot first of all you need to convert the plot into a RGB format image. So to do this we first need to grab the image from the buffer and convert into a 3D array. For this processes we need io and opencv.
import matplotlib.pyplot as plt
import cv2
import io
import numpy as np
figsize = #some figsize you want
fig = plt.figure(figsize = figsize)
ax = fig.add_subplot(111)
x=int(input("x coordinate: "))
y=int(input("y coordinate: "))
ax.plot(x,y,color='blue')
buf = io.BytesIO()
fig.savefig(buf, format = 'png', dpi = 180 )
buf.seek(0)
img_arr = np.frombuffer(buf.getvalue(), dtype = np.uint8 )
buf.close()
img = cv2.imdecode(img_arr,1)
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB )
This converts your plot to RGB 3D image that is stored as numpy array in img. Note that I have not kept this conversion in the function and the sole reason is this processing is done once and then the output is used multiple times. You can put this inside the function but it is not recommended as from your function I can see that you will be using it for color detection multiple times. So do this processing for small number of times and check on the result multiple times.
Your extract function will take this 3D array, take the value of RGB at point x,y and convert it into hexcolor code.
def rgb_to_hex(x,y):
rgb = ( img[x,y,0], img[x,y,1], img[x,y,2] )
return ( "#xxx" % rgb )
This will return the hex code that you can check for "black"
c = rgb_to_hex(x,y)
if c == '#000000':
pass
else
pass
NOTE: you can omit the hex conversion as you can directly check the tuple created for color at a particular cell.
And lastly care must be taken if the x,y is relative to an origin that is not the top left corner of the image. The x,y used in my code is absolute wrt to origin been the upper left corner.
My answer combines the ideas in
https://stackoverflow.com/a/3380739/17315172
https://stackoverflow.com/a/58641662/17315172
I am open for any rectifications and suggestions in this code.
CodePudding user response:
I think you must switch to SVG because that is easier to use as compared to using matplotlib in python.