-
-
Notifications
You must be signed in to change notification settings - Fork 7.9k
matplotlib.pyplot.imsave colormaps some grayscale images before saving them #3657
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Thanks, tagged as 1.5 as this is an api break to fix, but one I agree we should probably make. On the other hand, should we also be discouraging people from using mpl as an image I/O library? |
@jni Is there a misunderstanding here? imsave is doing exactly what the docstring says it will do. It is just as happy with uint16 as it would be with any other number type; if it sees a 2-D array, it colormaps it. If you want uint16, or uint8, to be understood by imsave as a 2-D array of gray values, then you need to add a kwarg to tell it this is what you want, and modify the code and docstring accordingly. None of your suggested "desired behaviours" is consistent with imsave. I don't see any reason to break the API here. |
First, where does it say this on the docstring? I'm on 1.4 and I get: Second, even if the docstring was clear, it's still wonky behaviour, and should not be the default. If @tacaswell you are correct that mpl may not be the library of choice for handling scientific data. On the other hand, it is extremely ingrained into the scientific Python ecosystem. For example, |
That last line, together with the vmin/vmax and cmap kwargs, is intended to mean that an MxN array is colormapped; and that is what it always has meant. Perhaps it could be worded better. I take it your interpretation is that MxN uint8 or uint16 should be treated as a gray scale image. That's a reasonable alternative. There is precedent for handling integer data differently from floating point; in fact, I introduced it in the Colormap.call() method. What I think is your alternative could be implemented with a kwarg to avoid breaking the API, as I suggested above. |
@efiring in turn, I did not mean any disrespect to the mpl team. God knows (as does GitHub =P), I've made more than my share of bad API choices. However, I still think |
@jni I'm getting a better picture of what you mean now; yes, I see the logic in having imsave/imread be inverses (provided a lossless format is used for both) in a data information sense. I still maintain that this can be done without breaking the API, by having the handling of a 2-D array determined by a kwarg. Whether the kwarg is necessary depends on whether there is user code that depends on uint8 and uint16 2-D arrays being color-mapped, as they are at present. The safest thing is to assume there is; I don't know if that is necessary in this case. |
Just thinking out loud, should the behavior be similar for imshow/imsave |
@WeatherGod, I don't understand; would you elaborate, please? |
Essentially, should imsave() produce a similar image as one would get if In other words, should the input handling/processing for On Sun, Oct 19, 2014 at 2:02 AM, Eric Firing notifications@github.com
|
On 2014/10/19, 4:25 AM, Benjamin Root wrote:
That's basically how it is implemented. |
thanx my friend ... since two days Im trying to solve this myth :D .. thanx a lot :) |
I've had recent real-world experiences with matplotlib.pyplot.imsave() and the issues discussed above. First, I'm relatively new to Python programming (just a few weeks), though I've been programming in other languages (C++, Java, C, others including many Assembly languages years ago) -- so I'm experienced with programming and APIs. I was trying to save multiple numpy arrays (each containing either a 2D color or 2D grayscale image). Each array was read from a file using (what I thought was its complement function), imread(). I encountered the exact problem described here, whereby my saved image was being saved not as grayscale but with some color-mapping. Since I'm new to Python and one never assumes a professional API/library has major bugs (or inconsistencies), I thus assumed my code and my newness to Python was causing this color-mapping. I investigated for over an hour, and eventually came to the conclusion my code was not causing this. More exploring, searching/reading... eventually I asked: "how can I be sure imsave() is doing what I want, maybe there's a missing parameter". So I researched further for info on imsave(), and after another hour stumbled onto this issue thread. I understand the point made by both @jni and @efiring. However, while being inexperienced with pyplot (and Python) though not a complete newbie, I feel imsave() and imread() should be reverse complements of each other (my problem arose because I assumed they were). This is a reasonable assumption for programmers to make. Most programmers, especially experienced programmers who are used to working with professional / curated libraries, will assume so. The ideal solution, one that causes minimal "breakage" to the existing API, would be to modify the imsave() function to first detect whether the image/matrix is 2D grayscale (i.e. has no 3rd tuple), and in that case only to internally force/default the appropriate "cmap" parameter and/optionally "dtype" parameter. This would make minimal if any change to its API definition, and so should affect no/few existing code. This problem cost me significant time (over 2 hours already). Worst of all, it makes me realize that Python library(ies?) I will import in future code may similarly be not necessarily consistent/well-designed. This I feel is the worst aspect -- for me and possibly for most developers -- to be left with the belief/realization that a specific library/package is "dangerous" or "tricky" to use. It's counter to why we create libraries/packages. I not mean to disparage or cast doubts on the people or development community who maintain this/other libraries -- but these are side-effects of such problems existing. I do not presume to know if there are other issues/constraints around this issue (of whether to change imsave() or not, so I offer this only as one firm data point of one user's recent experiences with this exact issue. Personally I would prefer to see imread() and imsave() to together act as a no-op, for a given image-type. At a minimum, the doc pages for both functions should be updated to elucidate the problem. If I may make a related suggestion (for the related doc pages)... the "cmap" parameter is not explained well on the [http://matplotlib.org/api/image_api.html#matplotlib.image.imread](matplotlib.org's imread() / imsave()) doc page. It should better explain the possible (or at least common) values for "cmap". It says this param defaults to the "rc image.cmap value", however even this value is not explained. I looked for this info in many places, starting with colors.Colormap, but found it explained nowhere. Only a runtime error msg from the Python interpreter gave me info I needed to proceed. |
We would be happy to see two PRs, one simple one to improve the documentation as you suggest immediately above, and a second to add the ability to write grayscale pngs as directed by a new kwarg. |
@sanjay-1 my recommendation would be to use scikit-image or imageio for IO. Now that |
To address the comment about this experience leaving a bad taste in your
mouth, so to speak, I totally understand. Matplotlib is one of the older
packages in the SciPy community, and has a very strict deprecation &
non-breakable policy. While this is great for scientists, this does mean we
carry a lot of historical baggage. Put on top of that the API originally
came from MatLab, and this is a recipe for confusion among users who are
not used to matlab's idiosyncracies.
Other packages in the SciPy community do have a lot of thought put into
them, and doesn't suffer from as much "organic growth" that mpl has. Not
that they don't have gotchas, I won't lie to you. But I think mpl is
probably the worst in this regard.
…On Jul 5, 2017 7:34 PM, "Juan Nunez-Iglesias" ***@***.***> wrote:
@sanjay-1 <https://github.com/sanjay-1> my recommendation would be to use
scikit-image or imageio for IO. Now that --pylab is essentially
deprecated, and scikit-image uses PIL by default, there's not much reason
to use mpl as an image IO library. Having said that, if you want to put
together a PR as suggested by @efiring <https://github.com/efiring>, I'm
sure future generations would be grateful!
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#3657 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AARy-ExQbVyz8_Y04NPHRYgbLktqzwm2ks5sLB2JgaJpZM4Cv9Kz>
.
|
Just pinging the dev team @matplotlib - what is the point of imsave at this point? I think a documentation update would help folks realize its not a straight image dump as you'd get from PIL and close this issue. So far as I can tell, its the same as imshow, but done directly on the data buffer, and not placed in axes etc. |
Took 8 years, but we got there @jni ! |
😂 😲 👏 👏 👏 also 👋! 😃 |
Encountered issue with imsave adding a fourth channel to my images and had to read through this thread. This behavior is rather frustrating. |
@ebalogun01 if you are experiencing problems with the latest version of Matplotlib, please open a new issue with details. |
Some people may be using matplotlib as an image IO library. Those people may also be scientists that care about their data being accurately saved on disk. They will be disappointed, however, to find that
imsave
does nothing of the sort:What is happening here is that
imsave
has encountered a data type it's not happy with (uint16, a commonly used data format in microscopy and probably other scientific imaging), and decided to silently colormap the values and save them as a uint8 RGBA image. (See #3616 for a longer discussion.) Adding insult to injury, the color mapping is to jet.In summary:
The text was updated successfully, but these errors were encountered: