Matplotlib contour plot labels - python

I'm combining a contour plot and an imshow. Depending on the colormap and the data, it sometimes happens that the contour labels have a color very similar to the pixmap and are therefore hard to read.
I remember seeing a matplotlib contour demo that showed how the text labels could be surrounded with a little white halo so as to make them readable regardless of the background, but I can't find it anymore. Does anyone know how to do that?

roadrunner66's answer worked, but it was not the halo effect I was looking for. However, I finally found it. You can use PathEffects as shown here:
http://matplotlib.org/examples/pylab_examples/patheffect_demo.html

Related

Interpolating colors inside a contour in opencv [python]

I am dealing with some images which contain tables and there are 1 or 2 stickers on them. What I am trying to do is getting rid of those stickers. Using color thresholding (in HSV) and contour detection I am able to create a mask for those stickers. Now I want those stickers to "dissolve" out from there (I don't know the correct term for this). While keeping those tables lines intact, so that my line detection works well (which I have to do after this cleaning).
I tried OpenCV's inpaint. But this doesn't work well here, because the sticker size is big enough.
See this example:
Part of the whole image where the sticker is sticking (inside contents are censored by me). It can be over horizontal lines, or vertical lines, or both. Basically, it's sticking somewhere on the table (maybe over some text too, but that can't be recovered anyway). The background won't be necessary whitish, it can be pink/orange/other colors.
This is the thresholded image, creating a mask of the sticker. We can also get the contour of this if required.
This is the result of cv.inpaint() with radius 3.
What I want is to reconstruct those lines.
My solution
Now my approach is to interpolate the colors in between the sticker contour, to fill it up. For each pixel inside the contour, I will do a vertical interpolation and a horizontal interpolation (interpolation of the boundary colors) and then fill that pixel with the average of both. I am hoping that this will preserve my vertical and horizontal lines at least. (Might fail if it's on a corner of the table). This will also keep the background smooth, my background can have some different colors.
Now my problem is how I can implement this. What I have are contours that I find using OpenCV's get_contours(). I don't know how to get the colors on its boundary and how to interpolate the in-between colors.
Any help is appreciated. Thanks in advance.
Due to confidentiality, I cannot share the whole image.
EDIT
I tried the seam-carving method (implementation). Here are the results:
Vertical seaming
Horizontal seaming
It works well once I know which one to use. And I am not sure how well it will do when we have both horizontal and vertical lines.
PS. Don't suggest a solution which needs to find lines and then work. Because there will be many lines in my whole image.
You can make synthetic example images. To better explain your issue.
As I got it you can use Poisson image editing. Just take a piece of clear paper image and paste it using poisson blending and the mask you extracted.
Check this github repo as instance for examples with code.

Is there a non-manual way to change matplotlib clabel locations?

I have a matplotlib contour plot of wind speed (m/s) with contour labels using clabel. Unfortunately, the default clabel locations are poorly placed - see the top right corner:
I would like to change this to make the plot easier to read.
I understand how to manually set the contour labels from the second response to this post.
However, I have so many contours and multiple figures that it seems like a very impractical solution to do this manually. Is there a non-manual way to clean up the contour label locations? Also, could I have more than one contour label per contour without doing it manually?

How to display axes on an image with opencv in python

Is there a way to show the row and column axes when displaying an image with cv2.imshow()? I am using the python bindings for opencv3.0
Not that I am aware of.
However, since you are using Python you are not constrained to use the rudimentary plotting capabilities of OpenCV HighGUI.
Instead, you can use the much more competent matplotlib library (or any of the other available Python plotting libraries).
To plot an image, including a default axis you do
import matplotlib.pyplot as plt
plt.imshow(image, interpolation='none') # Plot the image, turn off interpolation
plt.show() # Show the image window
I'm not sure I fully understand the question due to lack of info.
However you can use OpenCV's draw line function to draw a line from the example points (10,10) to (10,190), and another from (10,190) to (190,190)
On an example image that is 200X200 pixels in size, this will draw a line down the left hand side of the image, and a line along the bottom. You can then plot numbers or whatever you want along this line at increments of X-pixels.
Drawing text/numbers to an image is similar to drawing a line.
Once you have drawn the image, show with the usual image.imshow().
See OpenCV's drawing documentation here:
http://docs.opencv.org/modules/core/doc/drawing_functions.html
And an example to get you going can be found here:
http://opencvexamples.blogspot.com/2013/10/basic-drawing-examples.html#.VMj-bUesXuM
Hope this helps.

Blitting 2D image on top of 3D Matplotlib figure

I would like to blit a 2d image (like a png) to a location in 3-space on a 3D matplotlib figure. Essentially, I want the image to always be facing the user regardless of how the plot is rotated. It would be best if the blitted image did not scale as the user zoomed in and out as well.
One would think that this would be easy to do by accessing the low level rastering functions in matplotlib, but I can't find any documentation that describes what I would like to do.
If you put in an image as an annotation, zooming in on the axes will not scale the image. For example, see this demo. (To run the demo script, replace grace_hopper.png with lena.png.)
For example, just for an easy reference on zooming I've added a line of blue squares to the plot. The top image below show the unzoomed, and I've zoomed in in the lower one.

How to place country boarders as background for a plot with matplotlib?

I have some data made of coordinates and the count of each coordinate which I plot in a heatmap like this:
pyplot.subplot(211)
pyplot.scatter(longitudes, latitudes, c=counts)
pyplot.colorbar()
which is inspired by this great answer here in SO.
If you look closely you can see, that the dots shape the worldmap somehow. To underline this effect I'd like to put the real country boarders (simply drawn would be enough) as background to my plot. Is this possible with matplotlib? Maybe there is some (hidden) builtin in matplotlib?
You can likely achieve this if you have some image of the world map that you want as a background. You can read this into a numpy array and plot the image. Then you should be able to add your scatter plot overtop of the image. This matplotlib cookbook example shows how to insert images and such. There is also the matplotlib image tutorial that may be of use.
I've not used it, but you may also be interested in the basemap toolkit for matplotlib. In particular, the section on drawing a map background mentions specifically a drawcountries() method.

Categories

Resources