Why isn't matplotlib plotting all black lines in this grayscale image? - python

I have the following image (of dimensions 1151x781)
If I try to plot this image with matplotlib as follows
import matplotlib.pyplot as plt
img = plt.imread("this_image.png")
plt.figure(figsize=(10, 7))
plt.imshow(img, cmap="gray")
The result is the following
This happens if I execute this code by opening a Python shell from the terminal or in a jupyter notebook. The addition of the line matplotlib.use('TkAgg') before plotting does not seem to help.
I am on macOS Catalina (10.15.4) and I tried this with Python 3.7.1 and Matplotlib 3.0.2.
Do you also experience the same thing? What's the solution?
Please, do not tell me that the solution is to change the size of the figure! Because I know that, by changing the size of the figure, this problem can go away or new black lines are visualized. Of course, I don't want to lose time trying different sizes in order to understand which ones work out and, clearly, this solution is impractical and inflexible.

Change dpi of figure:
img = plt.imread('this_image.png')
plt.figure(figsize=(10,7), dpi=300)
plt.imshow(img, cmap='gray')
Output:

Related

Matplotlib bbox_inches issue

I have this very simple code:
import math
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(0, 2*math.pi)
fig, ax = plt.subplots()
ax.plot(x,np.sin(x))
plt.savefig('sinwave.png', bbox_inches='tight')
plt.show()
So what I would expect is that there is white background inside my plotting area, but no background around it, e.g. transparent background (only) behind the ticks and tick labels.
However, something is going wrong and it isn't working, the whole background is white. When I send it to a friend it works exactly as expected.
So I thought creating a new environment might fix it but the issue persisted. I tried it in ipython, jupyter lab and jupyter notebook, all with the same result (as to be expected but I just thought I would try). I'm using python 3.10.8 and matplotlib 3.6.2 on a Mac (2019 MacBook Pro) but it also doesn't work with other versions of python or matplotlib.
This is just a simple example but I have some 3-4 month old code which did exactly what I want back then and is now not doing it any more. Very odd.
Any ideas what might be going wrong? I really thought the new environment would fix the issue but no luck.
I'm fairly new to the community so let me know if you need any further details about my system (as it seems to be an issue with my computer/python install maybe??).
Cheers
Markus
Below are both images, you can't see the difference here as it's on white background but it's straight forward if opened e.g. in illustrator or photoshop.
fig = plt.figure()
fig.patch.set_facecolor('white')
fig.patch.set_alpha(0.6) #play with the alpha value
ax = fig.add_subplot(111)
ax.patch.set_facecolor('white')
ax.patch.set_alpha(0.0) #play with the alpha value
Then simply plot here
Plt.scatter(x,y)
Plt.show()

Python - save a figure with the same size and setting

I plot figures a lot during my python (through Spyder env.) usage. However, when I try to use plt.savefig('figure.png'), the saved figure has a different size from the inline figure plotted on Spyder.
For ex., when I use this command:
plt.savefig('fig1.png')
The saved figure looks like this:
Note that there's something weird with the saved figure, e.g.: the title is cropped, the size is not proportional.
However, the following is the inline figure:
I tried to modify the size through matplotlib.pyplot documentation but couldn't find such setting. Does anyone know how to save the figure with the exact setting as the inline plot?
The inline figure size plotted in Spyder (or any other IDE or editor) depends on how the editor handles showing figures.
If you want to have an exact size as output of your code, use figsize before plotting code. (It uses inches)
import matplotlib.pyplot as plt
plt.figure(figsize=(10, 10))
# Code to produce figure
You can also determine DPI when creating figure or saving.
plt.figure(figsize=(10, 10), dpi=300)
# or
plt.savefig(file_path, dpi=300)

Plot size changes on saving plot in matplotlib

I have plotted a graph with 14 subplots in matplotlib. In the window the plot looks like this-
I save this plot using following command-
import matplotlib.pyplot as plt
plt.savefig('img.png')
But the image that is saved looked like this-
Notice that the x axis labels get overlapped because the image is shrinked. The savefig() function has optional argument dpi, but it changes the resolution/quality of saved plot.
I also tried this, but it is used to improve image resolution.
I want the axis labels to be nicely spaced as in the window. Thanks
Ok, So I found the solution myself and posting it here for anyone who might face similar problem. I changed the figure size before saving and following code does the trick-
import matplotlib.pyplot as plt
fig =plt.gcf()
fig.set_size_inches(20, 11,dpi=100)
plt.savefig('img.png')

Editing Image using Python

I have to edit few image files using python. I have to open each image file, add few points at particular location & save the new edited image file(For fd my post-processing work).
Problem I am facing is:
1) I could not resize my plot axis. My plot axis should be 0-1 on both x &y with out any loss in image quality.
2) I could not save the edited image file, only the original file is getting saved.
This is what I tried:
im = Image.open('vortex.png')
implot = plt.plot(im)
fig, ax= plt.subplots()
myaximage = ax.imshow(im, aspect='auto', extent=(0,1,0,1),
alpha=0.5, origin='upper',
zorder=-2)
plt.implot([0.5], [0.5])
plt.show()
im.save("new","png")
Besides some small problems with your code, it seems you're basing your work on a wrong assumption: that you can turn a image into a matplotlib plot.
An image is simply a collection of pixels. While your brain interprets it as a plot, with a axis, and maybe a grid, you can't expect the computer to do so. You can't manipulate a collection of pixels as if it were a plot - it isn't.
You need to forget about matplotlib and use the image editing resourses of PIL.
Not sure about the axis change, but the saving of the file, see this post:
Python Imaging Library save function syntax
From the PIL Handbook:
im.save(outfile, options...)
im.save(outfile, format, options...)
Simplest case:
im.save('my_image.png')

Matplotlib: poor resolution of PDF figures with hatching

When using Matplotlib to generate figures with hatching (e.g. pie, bar, bubble charts), I'm having some trouble getting decent resolution out of the PDF version of the figure. Saving as EPS is fine, but as soon as I use epstopdf or MPL's savefig(*.pdf), the hatching becomes pixellated and distored... the vector nature of the image appears to have been lost.
See minimal code below.
from matplotlib import pyplot as plt
# Define hatching styles
hatching = ["/", "o"]
fig, ax = plt.subplots()
wedges, texts = ax.pie([0.4, 0.6], colors=("SteelBlue", "Tomato"))
# Apply the hatching
for j, patch in enumerate(wedges): patch.set_hatch(hatching[j])
fig.savefig("hatchtest.pdf")
I've used Gimp to zoom in on a part of the plot to illustrate the difference...
Zoomed in on the EPS figure
Zoomed in on the PDF figure
As for system specific details, I'm using Ubuntu 13.04, Python 2.7.4 with MPL 1.2.1. I've tried different backends but nothing seems to resolve this. I'd ideally like to have nice vector images in EPS and PDF so that it's all journal-friendly. Any pointers would be much appreciated.
Just a problem with Evince PDF viewer. Viewing in Adobe Reader or printing the plot gives the desired result.

Categories

Resources