Matplotlib plot with AGG backend not working - python

Is there something I am missing? I would like to run software without having to go install a monitor on a virtual machine and hit a key every time it processes another image. The concept of forcing the GUI dependence on the user seems rather odd... Why assume a physical monitor?
I have jumped through the hoops for the "AGG" backend to remove the X server dependence, but this changes nothing. How can I force it to not try and draw to a non-existent display?
import cv2
import numpy as np
import os
from decimal import Decimal
from PIL import Image
from PIL.ExifTags import TAGS
import time
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
chans = cv2.split(img)
colors = ("b", "g", "r")
plt.figure()
#plt.axis('off')
features = []
# loop over the image channels
for (chan, color) in zip(chans, colors):
chist = cv2.calcHist([chan], [0], None, [256], [0, 256])
features.extend(chist)
# plot the histogram
plt.plot(chist, color = color)
plt.xlim([0, 256])
plt.savefig('histchart.png', bbox_inches=0)
No matter what I do, it still forces that stupid GUI dependance. Is there any way to totally and completely remove the dependency?

Related

Incorrect label assignment after watershed segmentation (Python)

I am segmenting some particles using skimage.segmentation.watershed.
This works quite well, and I manage to separate them adecuately (see image).
Image after segmentation.
However, when I use ndi.label to label the different regions, not all the segments get separated, and some are assigned the same label (even if with watershed they were correctly segmented) (image 2, for instance top left particle) after labeling assignment. Notice how particles previously separated are assigned the same label.
I am relatively new in Python and do not know what else I can try to solve this. I would appreciate if you could give me any help. Thanks in advance :)
The code I am using is (I have it in a for loop since I want to automatize the process for the analysis of several images simultaneously):
#import hyperspy for reading directly ser or emd files
import hyperspy.api as hs
#The scikit image library will be used for segmenting the images
from skimage.exposure import histogram
from skimage.color import label2rgb
from skimage import data, io, filters
from skimage.filters import threshold_local, threshold _yen, threshold_li
from skimage.filters import try_all_threshold
from skimage.filters import gaussian
from skimage.feature import peak_local_max
from skimage.feature import canny
from skimage import measure
from skimage.morphology import label
from skimage.morphology import remove_small_objects
from skimage.draw import ellipse
from skimage.measure import label, regionprops, regionprops_table
from skimage.transform import rotate
from skimage.segmentation import watershed
#matplotlib for performing plots
import matplotlib as mpl
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
#Basic packages (math and statistics)
import pandas as pd
import numpy as np
from scipy import ndimage as ndi
from scipy import stats
import math
import glob
import seaborn as sns
#load data
s=hs.load(folder+'*.emi',stack=True)
#threshold
thresh=threshold_li(s.data)
binary=s>thresh
#Cleaning
cleaned=remove_small_objects(binary.data, min_size=5)
Segmentation itself
#Define variables needed
dist=np.zeros([cleaned.shape[1],cleaned.shape[1]])
water=np.zeros([cleaned.shape[0],cleaned.shape[1],cleaned.shape[1]])
mask=np.zeros(dist.shape, dtype=bool)
markers,_=ndi.label(mask)
water_particles=np.zeros([cleaned.shape[0],cleaned.shape[1],cleaned.shape[1]])
eq_diam_total=np.array([])
#for loop for segmenting all the images using watershed.
#I will use the commented "for i in range (cleaned.shape[0])"
#once I manage to solve the segmentation issue:
#for i in range (cleaned.shape[0]):
for i in range(2,3):
dist = ndi.distance_transform_edt(cleaned[i,:,:]) #make distance map
maxima=peak_local_max(gaussian(dist, sigma=1.5),threshold_rel=None,
min_distance=5) # find local maxima
print('maxima',maxima.shape)
mask[tuple(maxima.T)]=True
markers,_=ndi.label(mask)
print('markers',markers.shape)
#segment
water[i,:,:]=watershed(-dist, markers,mask=cleaned[i,:,:])
print('water', water.shape)
#label each particle
water_particles[i,:,:], water_labels = ndi.label(water[i,:,:])
print('water_particles',water_particles.shape)
print('water_labels',water_labels)
Plot after segmentation
%matplotlib inline
from skimage import color
fig,axes=plt.subplots(1, 2, sharey=True)
axes[0].imshow(color.label2rgb(water[i,:,:]))
axes[0].axis('off')
axes[0].set_title('After watershed segmentation')
axes[1].imshow(color.label2rgb(water_particles[i,:,:]))
axes[1].axis('off')
axes[1].set_title('After label')
The output of skimage.segmentation.watershed is a labeled image, it can go directly into the measurement function (regionprops).
Also, that watershed function will take all local minima as markers, you don’t need to find these yourself. Simplified code:
from scipy import ndimage as ndi
from skimage.segmentation import watershed
# ...
dist = ndi.distance_transform_edt(cleaned[i,:,:]) #make distance map
water_particles[i,:,:] = watershed(-dist, markers,mask=cleaned[i,:,:])
If you want to receive an image you can label yourself (for whatever reason), then add the watershed_line=True argument. This will keep a separation between each region (basin) so that the labeling algorithm can identify them.

Matplotlib.collections.PathCollection

https://www.youtube.com/watch?v=pl3D4SosO_4&list=PL9mhv0CavXYjiIniCLj_5KKN58PaxJBVj&index=2
Right at time stamp 2:13.
I am trying to follow a youtube tutorial and I have hit a road block. There is no documentation online that tells me how to implement matplotlib.collections.PathCollection
The youtuber in this video that I am following runs the first bit of his code (at about 2:13) and a plot appears with some color data points. Above this plot it says <matplotlib.collections.PathCollection at 0x208cd62cef0>
If anyone could tell me how this youtuber got this plot to appear I would be forever grateful.
I have found documentation for matplotlib.collections, but zero information on how it is used, I asked the youtuber how he got to this point in the comments and am waiting on an answer.
Thank you Craig, I am adding the code that doesn't work for me here
EDIT:
(I have been attempting this in a pycharm IDE and the video is using Jupyter, idk if that makes a difference)
import numpy as np
from matplotlib import plyplot as plt
from sklearn.datasets import make_blobs
X,y = make_blobs(n_samples = 500, centers = 5, random_state = 3)
plt.figure(0)
plt.grid(True)
plt.scatter(X[:,0], X[:,1],c=y)
when this is run in the video a plot with color clusters appears.
Maybe I should be trying this in jupyter, maybe some image libraries are pre-loaded there?
Jupyter is a special interactive environment and it automatically renders matplotlib plots when it runs a cell that creates a plot. If you are doing the same thing in an IDE, then you will need to explicitly render the plot by calling plt.show() when you want the plot to appear. You can do this for your code by adding it to the end:
import numpy as np
from matplotlib import plyplot as plt
from sklearn.datasets import make_blobs
X,y = make_blobs(n_samples = 500, centers = 5, random_state = 3)
plt.figure(0)
plt.grid(True)
plt.scatter(X[:,0], X[:,1],c=y)
plt.show() # <-- show the plot

matplotlib does not show the image

from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
i = Image.open('images/dot.png')
iar = np.asarray(i)
plt.imshow(iar)
plt.show()
I have the image called dot.png in the same directory but it is not working.
When I start the program no errors detected. It runs fine. But the matplotlib tool not working.
The window look like this:

Seaborn displays different color for different run

I followed the setting from here to make matplotlib/seaborn available to display in Zeppelin. However, with the following code:
%python
import seaborn as sns
import matplotlib
import numpy as np
matplotlib.use('Agg')
import matplotlib.pyplot as plt
plt.rcdefaults()
import StringIO
def show(p):
img = StringIO.StringIO()
p.savefig(img, format='svg')
img.seek(0)
print "%html <div style='width:600px'>" + img.buf + "</div>"
""" Prepare your plot here ... """
# Use the custom show function instead of plt.show()
x = np.random.randn(100)
ax = sns.distplot(x)
show(sns.plt)
It is strange that the displayed figure show the desired lightblue color the first time I run the code but will display different colors if I execute the same piece of code. Is there a way to force seaborn to keep constant color being displayed? Thanks.
It's not entirely clear what is meant by "running a second time".
However you may try to actually close the figure before running it again. E.g.
plt.close("all")
in order to make sure, a new figure is created which should have the same default color every time.

Ipython notebook (jupyter),opencv (cv2) and plotting?

Is there a way to use and plot with opencv2 with ipython notebook?
I am fairly new to python image analysis. I decided to go with the notebook work flow to make nice record as I process and it has been working out quite well using matplotlib/pylab to plot things.
An initial hurdle I had was how to plot things within the notebook. Easy, just use magic:
%matplotlib inline
Later, I wanted to perform manipulations with interactive plots but plotting in a dedicated window would always freeze. Fine, I learnt again that you need to use magic. Instead of just importing the modules:
%pylab
Now I have moved onto working with opencv. I am now back to the same problem, where I either want to plot inline or use dedicated, interactive windows depending on the task at hand. Is there similar magic to use? Is there another way to get things working? Or am I stuck and need to just go back to running a program from IDLE?
As a side note: I know that opencv has installed correctly. Firstly, because I got no errors either installing or importing the cv2 module. Secondly, because I can read in images with cv2 and then plot them with something else.
This is my empty template:
import cv2
import matplotlib.pyplot as plt
import numpy as np
import sys
%matplotlib inline
im = cv2.imread('IMG_FILENAME',0)
h,w = im.shape[:2]
print(im.shape)
plt.imshow(im,cmap='gray')
plt.show()
See online sample
For a Jupyter notebook running on Python 3.5 I had to modify this to:
import io
import cv2
import numpy as np
from IPython.display import clear_output, Image, display
import PIL.Image
def showarray(a, fmt='jpeg'):
a = np.uint8(np.clip(a, 0, 255))
f = io.BytesIO()
PIL.Image.fromarray(a).save(f, fmt)
display(Image(data=f.getvalue()))
There is also that little function that was used into the Google Deepdream Notebook:
import cv2
import numpy as np
from IPython.display import clear_output, Image, display
from cStringIO import StringIO
import PIL.Image
def showarray(a, fmt='jpeg'):
a = np.uint8(np.clip(a, 0, 255))
f = StringIO()
PIL.Image.fromarray(a).save(f, fmt)
display(Image(data=f.getvalue()))
Then you can do :
img = cv2.imread("an_image.jpg")
And simply :
showarray(img)
Each time you need to render the image in a cell

Categories

Resources