Last updated: Apr 11, 2024
Reading timeยท2 min
The NumPy "ValueError: assignment destination is read-only" occurs when you try to assign a value to a read-only array.
To solve the error, create a copy of the read-only array and modify the copy.
You can use the flags
attribute to check if the array is WRITABLE
.
from PIL import Image import numpy as np img = np.array(Image.open('house.png')) print(img.flags)
Running the code sample produces the following output:
C_CONTIGUOUS : True F_CONTIGUOUS : False OWNDATA : True WRITEABLE : True # ๐๏ธ must be set to True ALIGNED : True WRITEBACKIFCOPY : False
In your case, WRITEABLE
will likely be set to False
.
In older NumPy versions, you used to be able to set the flag to true
by
calling the setflags()
method.
from PIL import Image import numpy as np img = np.array(Image.open('house.png')) print(img.flags) img.setflags(write=1)
However, setting the WRITEABLE
flag to True
(1
) will likely fail if the
OWNDATA
flag is set to False
.
You will likely get the following error:
To solve the error, create a copy of the array when converting it from a Pillow Image to a NumPy array.
from PIL import Image import numpy as np # โ Create a copy of the array when converting img = np.array(Image.open('house.png')) print(img.flags)
Passing the Pillow Image to the numpy.array() method creates a copy of the array.
You can also explicitly call the copy()
method.
from PIL import Image import numpy as np # โ Create copy of array when converting img = np.array(Image.open('house.png')).copy() # called copy() # C_CONTIGUOUS : True # F_CONTIGUOUS : False # OWNDATA : True # WRITEABLE : True # ๐๏ธ must be set to True # ALIGNED : True # WRITEBACKIFCOPY : False print(img.flags)
You can also call the copy()
method on the Pillow Image and modify the copy.
from PIL import Image img = Image.open('house.png') # ๐๏ธ create a copy of the image img_copy = img.copy()
The image copy isn't read-only and allows assignment.
You can change the img_copy
variable without getting the "assignment
destination is read-only" error.
You can also use the numpy.copy() method.
from PIL import Image import numpy as np img = Image.open('house.png') # ๐๏ธ create a copy of the image img_copy = np.copy(img) print(img_copy)
The numpy.copy()
method returns an array copy of the given object.
The only argument we passed to the method is the image.
You can safely modify the img_copy
variable without running into issues.
You most likely don't want to make changes to the original image.
Creating a copy and modifying the copy should be your preferred approach.
If you got the error when using the np.asarray()
method, try changing it to
np.array()
.
Change the following:
# โ๏ธ Before from PIL import Image import numpy as np img = np.asarray(Image.open('house.png')) print(img.flags)
To the following:
# โ After from PIL import Image import numpy as np img = np.array(Image.open('house.png')) print(img.flags)
As long as the WRITEABLE
flag is set to True
, you will be able to modify the
array.
You can learn more about the related topics by checking out the following tutorials: