Skip to content

[Bug]: I give an RGB image to imsave but I don't have the right color map! #29183

Closed

Description

@zef126

Bug summary

When I give an RGB image as a list of list of list to imsave, I don't have the right colormap and there is no rgb colormap!

Code for reproduction

import matplotlib.pyplot as plt
I = plt.imread("notre-dame.jpg")
m,n,p = I.shape #m=largeur, n=hauteur, p=uplet
J=[[[0 for d in range(p)] for e in range(n)] for f in range(m)]
K=[[[0 for d in range(p)] for e in range(n)] for f in range(m)]
L=[[[0 for d in range(p)] for e in range(n)] for f in range(m)]
for i in range(m) :
    for j in range(n) :
        J[i][j]=[int(I[i][j][0]),0,0]
        K[i][j]=[0,int(I[i][j][1]),0]
        L[i][j]=[0,0,int(I[i][j][2])]
fig, ax=plt.subplots(4,figsize=(28,10))
ax[0].imshow(I)
ax[1].imshow(J)
ax[2].imshow(K)
ax[3].imshow(L)
ax[0].set_axis_off()
ax[1].set_axis_off()
ax[2].set_axis_off()
ax[3].set_axis_off()
ax[0].set_title('Image complete')
ax[1].set_title('Composante rouge')
ax[2].set_title('Composante bleue')
ax[3].set_title('Composante verte')
fig.suptitle("Image de Notre-Dame", x=0.51,y=.93)
plt.imsave("Notre-Dame_rouge.png",J) #The problem is here!
plt.savefig("Notre-Dame_composante_ex1.png",dpi=750,bbox_inches="tight")
plt.savefig("Notre-Dame_composante_ex1.pdf",dpi=750,bbox_inches="tight")
plt.show()

Actual outcome

Notre-Dame_rouge

Expected outcome

Notre-Dame_composante_ex1
The red one in a png image!

Additional information

notre-dame
The original image

Operating system

Win 11

Matplotlib Version

3.9.2

Matplotlib Backend

module://matplotlib_inline.backend_inline

Python version

3.11.10

Jupyter version

No response

Installation

conda

Activity

  1. tacaswell commented on Nov 25, 2024

    @tacaswell
    Member

    The source of the problem is that in figimage we only check for RGB if the input is already a numpy array. Is there a reason you need to work with list-of-list-of-list? Using numpy (which I is already a numpy array) the code becomes simpler (no nested loop), faster (numpy does array work at or near c-speed), and avoids the bug:

    import matplotlib.pyplot as plt
    import numpy as np
    I = plt.imread("notre-dame.jpg")
    
    J = np.zeros_like(I)
    # RGB version of the image with only one plane non-zero
    J[..., 0] = I[..., 0]
    K = np.zeros_like(I)
    K[..., 0] = I[..., 1]
    L = np.zeros_like(I)
    L[..., 0] = I[..., 2]
    
    
    # share the axis so that panning / zooming on one pans/zooms on all
    fig, axs = plt.subplots(4, figsize=(28, 10), sharex='all', sharey='all')
    # loop over axes, data, and title strings
    for ax, data, title in zip(
        axs,
        (I, J, K, L),
        ("Image complete", "Composante rouge", "Composante bleue", "Composante verte"),
    ):
        ax.imshow(data)
        ax.set_title(title)
    
    fig.suptitle("Image de Notre-Dame", x=0.51, y=0.93)
    
    fig.savefig("Notre-Dame_composante_ex1.png", dpi=750, bbox_inches="tight")
    fig.savefig("Notre-Dame_composante_ex1.pdf", dpi=750, bbox_inches="tight")
    
    plt.imsave("Notre-Dame_rouge.png", J)  # The problem is here!
    plt.show()

    As a short-term fix you can also do np.array(J) before passing to fig.imsave which will go through the correct code path.

  2. added
    Difficulty: Easyhttps://matplotlib.org/devdocs/devel/contribute.html#good-first-issues
    🌱 Good first issueOpen a pull request against these issues if there are no active ones!
    on Nov 25, 2024
  3. github-actions commented on Nov 25, 2024

    @github-actions

    Good first issue - notes for new contributors

    This issue is suited to new contributors because it does not require understanding of the
    Matplotlib internals. To get started, please see our contributing
    guide
    .

    We do not assign issues. Check the Development section in the sidebar for linked pull
    requests (PRs). If there are none, feel free to start working on it. If there is an open PR, please
    collaborate on the work by reviewing it rather than duplicating it in a competing PR.

    If something is unclear, please reach out on any of our communication
    channels
    .

  4. tacaswell commented on Nov 25, 2024

    @tacaswell
    Member

    This is a good first issue as it should require no API choices and we have a good reference for the expected behavior already in the code base.

    The issue is that when passing a list-of-list-of-list to plt.imsave and saving to a format that pillow and write the check that sees if it is an RGB image (which should not be color mapped) or a 1-channel luminescence image (which should) is avoided and we always color map.

    The steps are:

    • look at Axes.imshow to see how we do the input normalization there
    • do the same thing is matplotlib.image.imsave
    • add a test (round-trip with imread and a small synthetic RGB image)
  5. added this to the v3.10.1 milestone on Nov 25, 2024
  6. Frostbyte72 commented on Nov 25, 2024

    @Frostbyte72

    Hi I am a new contributor to opensource and believe I can fix this could I be assigned to this issue?

  7. tacaswell commented on Nov 25, 2024

    @tacaswell
    Member

    We do not assign issues.

    Please review https://matplotlib.org/stable/devel/index and open a PR when you are ready!

  8. zef126 commented on Nov 25, 2024

    @zef126
    Author

    Thank you so much for your help...it is very useful, I will try to use arrays!
    The point is that I am in preparation class in France and parts of the code are strictly imposed by the teacher!

  9. zef126 commented on Nov 25, 2024

    @zef126
    Author

    It is the first repo where i fond kindness and attention, it is really appreciated!

  10. zef126 commented on Nov 25, 2024

    @zef126
    Author

    Now it's just a code issue...I don't understand why I get that:
    Notre-Dame_composante_ex1_2
    Instead of that:
    Notre-Dame_composante_ex1
    with your code @tacaswell !
    And by the way how can i save my lists in rgb files ...if it's possible?
    I tried to convert them in numpy.arrays like that:
    plt.imsave("Notre-Dame_rouge.png", np.array(J))
    but it returned that:
    ValueError: Image RGB array must be uint8 or floating point; found int64
    Thank you again for your help!

  11. QuLogic commented on Nov 26, 2024

    @QuLogic
    Member
    J[..., 0] = I[..., 0]
    K = np.zeros_like(I)
    K[..., 0] = I[..., 1]
    L = np.zeros_like(I)
    L[..., 0] = I[..., 2]

    K and L should use 1 and 2, respectively.

  12. tacaswell commented on Nov 26, 2024

    @tacaswell
    Member

    🤦🏻

    as noteed, should be

    J[..., 0] = I[..., 0]
    K = np.zeros_like(I)
    K[..., 1] = I[..., 1]
    L = np.zeros_like(I)
    L[..., 2] = I[..., 2]

    and np.asarray(J, dtype=np.int8)

  13. zef126 commented on Nov 26, 2024

    @zef126
    Author

    Thank you very much!
    I just got this for saving the list of list of list:

    plt.imsave("Notre-Dame_rouge.png", np.asarray(J, dtype=np.int8))
    
    OverflowError: Python integer 128 out of bounds for int8
  14. 10 remaining items

  15. aragan22 commented on Feb 18, 2025

    @aragan22

    Below is the full code for the script, including the fix for the imsave function to handle nested lists properly. I included headers to describe exactly what each code block function as and how it was changed.

    @aragan22 This is not adding meaningfully to the issue. You are only rewriting the original restating the original minimal example with comments - but the example and issue is well understood. Nobody with the capability of fixing the issue needs these comments. Please think carefully to not post repetitive or unneeded stuff.

    Apologies, I did not mean to comment that portion. That was simply for myself as I tried to understand the issue and work around it in my own way. Thank you for pointing this out, apologies again for the confusion.

  16. modified the milestones: v3.10.1, v3.10.2 on Feb 21, 2025
  17. Dronten commented on Mar 22, 2025

    @Dronten

    is this issue still up and can i work in this ?

  18. rcomer commented on Mar 22, 2025

    @rcomer
    Member

    @Dronten yes it looks like #29203 has stalled so you are welcome to go ahead. Please see our contributors’ guide:
    https://matplotlib.org/devdocs/devel/index.html

  19. Aftabby commented on Apr 8, 2025

    @Aftabby

    Has the issue been solved? Else I'd like to take over.

  20. timhoffm commented on Apr 9, 2025

    @timhoffm
    Member

    @Aftabby it looks like #29203 has stalled so you are welcome to go ahead. Please see our contributors’ guide:
    https://matplotlib.org/devdocs/devel/index.html

  21. guillermodotn commented on Apr 16, 2025

    @guillermodotn
    Contributor

    I have opened PR #29931 for this issue, based on the latest code review in #29203.

  22. modified the milestones: v3.10.2, v3.10.3 on May 2, 2025
  23. jk2500 commented on May 6, 2025

    @jk2500

    Hey there, I tried running the code in the snippet and it shows the expected output. Does this mean the issue can be closed?

  24. timhoffm commented on May 7, 2025

    @timhoffm
    Member

    Yes, closed by #29931.

  25. modified the milestones: v3.10.3, v3.10.2 on May 7, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Difficulty: Easyhttps://matplotlib.org/devdocs/devel/contribute.html#good-first-issuesstatus: confirmed bug🌱 Good first issueOpen a pull request against these issues if there are no active ones!

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions