I have the following PBM file (ASCII encoding) and I need to put each line (excluding P1,#feep.pbm,and24 7. Through a series of functions.
P1
# feep.pbm
24 7
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 1 1 1 1 0 0 1 1 1 1 0 0 1 1 1 1 0 0 1 1 1 1 0
0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 1 0
0 1 1 1 0 0 0 1 1 1 0 0 0 1 1 1 0 0 0 1 1 1 1 0
0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0
0 1 0 0 0 0 0 1 1 1 1 0 0 1 1 1 1 0 0 1 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
I have seen several advice by changing them to list or numpy array for convinience. But the problem is how to do this in Python? I found about a similar solution here https://stackoverflow.com/questions/4270700/how-to-write-pil-image-filter-for-plain-pgm-format but it does not work on my case.
An easy way is just use list slice.Try code below:
from pprint import pprint
with open("feep.ascii.pbm", "r") as f:
lines = f.readlines()
arr = []
for line in lines[3:]:
t = list(map(int, line.strip().split()))
arr.append(t)
pprint(arr)
Or with an easy list comprehension:
from pprint import pprint
with open("feep.ascii.pbm", "r") as f:
arr = [list(map(int, line.strip().split())) for line in f.readlines()[3:]]
pprint(arr)
All of them print:
[[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0],
[0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0],
[0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0],
[0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0],
[0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]
[[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
[0 0 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
[0 0 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
[0 1 1 1 0 0 0 0 0 1 1 0 0 3 3 0 0 0 4 4 0 0 0 5 5 5 5 0 0 2 2 2 2 2 0 2 2 2 2 2 0 0 0 6 6 6 6 6 6 0 6 6 6 6]
[0 1 1 0 0 0 0 0 0 0 0 0 0 3 3 0 0 0 4 4 0 0 5 5 5 5 5 5 0 2 2 2 2 2 2 2 2 2 2 2 2 0 0 6 6 6 6 6 6 6 6 6 6 6]
[1 1 1 0 0 0 0 0 0 0 0 0 0 3 3 0 0 0 4 4 0 5 5 5 0 0 5 5 5 0 2 2 0 0 2 2 0 0 0 2 2 0 0 6 6 0 0 6 6 6 0 0 6 6]
[1 1 1 0 0 0 0 0 0 0 0 0 0 3 3 0 0 0 4 4 0 5 5 5 5 0 0 0 0 0 2 2 0 2 2 2 0 0 0 2 2 2 0 6 6 0 0 0 6 6 0 0 6 6]
[1 1 1 0 0 0 0 0 0 0 0 0 0 3 3 0 0 0 4 4 0 0 5 5 5 5 5 5 0 0 2 2 0 2 2 2 0 0 0 2 2 2 0 6 6 0 0 0 6 6 0 0 6 6]
[0 1 1 0 0 0 0 0 0 7 0 0 0 3 3 0 0 0 4 4 0 0 0 0 5 5 5 5 5 0 2 2 0 2 2 2 0 0 0 2 2 2 0 6 6 0 0 0 6 6 0 0 6 6]]
As a first step I want the pixels different than 0 to be white and the 0 pixels to be black.what i did to transform the none 0 values all to 1:
binary_transform = np.array(labels).astype(bool).astype(int)
and it worked then i want to transform the list of arrays of 1s and 0s to image, what i tried:
from PIL import Image
img = Image.fromarray(binary_transform, '1')
img.save('image.png')
the docs for Image.fromarray can be found here https://pillow.readthedocs.io/en/3.1.x/reference/Image.html
It didn't work then i tried the following:
import png
png.from_array(binary_transform, 'L').save('image.png')
Referring to the docs 'L' is for grayscale while i want binary but i didn't see a binary option, the docs https://pythonhosted.org/pypng/png.html
and i got this error ValueError: bitdepth (64) must be a positive integer <= 16
Though you don't say that explicitly, the fact that you said "As a first step...", makes me think you are heading towards a greyscale palette image:
import numpy as np
from PIL import Image
labels=[[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,1,1,1,0,0,0,0,0,1,1,0,0,3,3,0,0,0,4,4,0,0,0,5,5,5,5,0,0,2,2,2,2,2,0,2,2,2,2,2,0,0,0,6,6,6,6,6,6,0,6,6,6,6],
[0,1,1,0,0,0,0,0,0,0,0,0,0,3,3,0,0,0,4,4,0,0,5,5,5,5,5,5,0,2,2,2,2,2,2,2,2,2,2,2,2,0,0,6,6,6,6,6,6,6,6,6,6,6],
[1,1,1,0,0,0,0,0,0,0,0,0,0,3,3,0,0,0,4,4,0,5,5,5,0,0,5,5,5,0,2,2,0,0,2,2,0,0,0,2,2,0,0,6,6,0,0,6,6,6,0,0,6,6],
[1,1,1,0,0,0,0,0,0,0,0,0,0,3,3,0,0,0,4,4,0,5,5,5,5,0,0,0,0,0,2,2,0,2,2,2,0,0,0,2,2,2,0,6,6,0,0,0,6,6,0,0,6,6],
[1,1,1,0,0,0,0,0,0,0,0,0,0,3,3,0,0,0,4,4,0,0,5,5,5,5,5,5,0,0,2,2,0,2,2,2,0,0,0,2,2,2,0,6,6,0,0,0,6,6,0,0,6,6],
[0,1,1,0,0,0,0,0,0,7,0,0,0,3,3,0,0,0,4,4,0,0,0,0,5,5,5,5,5,0,2,2,0,2,2,2,0,0,0,2,2,2,0,6,6,0,0,0,6,6,0,0,6,6]]
binary_transform = np.array(labels).astype(np.uint8)
img = Image.fromarray(binary_transform, 'P')
img.save('image.png')
Note that I have resized and contrast-stretched the image for display purposes.
If you really only want a true binary, black and white image, use:
binary_transform = np.array(labels).astype(np.uint8)
binary_transform[binary_transform>0] = 255
img = Image.fromarray(binary_transform, 'L')
img.save('image.png')
If I understand you right, you want the image to appear binary, i.e., just black and white, no grey. If that's the case, OpenCV is your friend:
import cv2
import numpy as np
binary_transform = np.array(labels).astype(np.uint8)
_,thresh_img = cv2.threshold(binary_transform, 0, 255, cv2.THRESH_BINARY)
cv2.imwrite('image.png', thresh_img)
Of course PIL will work as well, you just need to adjust your non-zero values.
binary_transform = np.array(labels).astype(np.uint8)
binary_transform[binary_transform > 0] = 255
img = Image.fromarray(binary_transform, 'L')
img.save('image.png')
The other answers (all good!) use OpenCV or PIL. Here's how you could create the image using numpngw, a small library that I wrote to create PNG files from numpy arrays.
First, here's my data for the example:
In [173]: x
Out[173]:
[[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 1, 1, 1, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 1, 1, 1, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 1, 1, 1, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 1, 1, 1, 0, 3, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 0, 2, 2, 2, 2, 2, 0],
[0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 0, 2, 2, 2, 2, 2, 0],
[0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 0, 2, 2, 2, 2, 2, 0],
[0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 0, 2, 2, 2, 2, 2, 0],
[0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 0, 2, 2, 2, 2, 2, 0],
[0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 0, 2, 2, 2, 2, 2, 0],
[0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 0, 2, 2, 2, 2, 2, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]
Create the image using numpngw.write_png():
In [174]: import numpy as np
In [175]: import numpngw
In [176]: numpngw.write_png("foo.png", (np.array(x) > 0).astype(np.uint8), bitdepth=1)
Here's the image:
I have a data frame with a class value I am trying to predict. I am interested in label 1.
I am trying to determine if turn plays a role for a given key value.
For a given key value of say 1 and a turn number of 1, what percentage of turns have a class value of 1?
For example for the given data
key=1,turn=1,8/11 have a class label 1
key=1,turn=2,5/6 have a class label 1
How can I plot a percentage histogram for this type of data?
I know a normal histogram using matplotlib
import matplotlib
matplotlib.use('PS')
import matplotlib.pyplot as plt
plt.hist()
but what values I would use to get the percentage histogram?
Sample columns from the dataframe
key=[
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
]
turn=[
1
1
1
1
1
1
1
1
1
1
1
2
2
2
2
2
2
3
3
3
3
3
3
3
3
3
3
3
3
3
3
4
4
4
4
4
4
1
2
2
2
2
2
2
3
3
3
3
3
3
3
3
3
3
3
4
4
4
4
4
4
4
4
4
4
4]
class=[0
1
0
0
1
1
1
1
1
1
1
1
1
1
1
0
1
1
0
0
1
1
0
1
0
1
1
0
1
1
0
0
1
0
1
0
0
0
0
0
1
1
1
1
0
1
1
0
0
1
0
0
0
0
0
1
0
1
1
0
0
1
1
1
0
0]
Since the concepts from the linked question are apparently not what you need, an alternative would be to produce pie charts as shown below.
key=[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 ]
turn=[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4]
clas=[0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0]
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
df=pd.DataFrame({"key":key, "turn":turn, "class":clas})
piv = pd.pivot_table(df, values="class", index="key", columns="turn")
print piv
fig, axes = plt.subplots(ncols=4, nrows=2)
for i in range(2):
axes[i,0].set_ylabel("key {}".format(i+1))
for j in range(4):
pie = axes[i,j].pie([piv.values[i,j],1.-piv.values[i,j]], autopct="%.1f%%")
axes[i,j].set_aspect("equal")
axes[0,j].set_title("turn {}".format(j+1))
plt.legend(pie[0],["class 1","class 0"], bbox_to_anchor=(1,0.5), loc="right",
bbox_transform=plt.gcf().transFigure)
plt.show()
I'm trying to display a python 2D list without the commas, brackets, etc., and I'd like to display a new line after every 'row' of the list is over.
This is my attempt at doing so:
ogm = repr(ogm).replace(',', ' ')
ogm = repr(ogm).replace('[', ' ')
ogm = repr(ogm).replace("'", ' ')
ogm = repr(ogm).replace('"', ' ')
print repr(ogm).replace(']', ' ')
This is the input:
[[0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 1, 0, 1, 0, 0, 0, 0, 0, 0], [1, 1, 1, 0, 0, 0, 0, 0, 0, 0], [0, 1, 1, 0, 0, 0, 0, 0, 1, 1], [0, 0, 0, 0, 0, 0, 1, 1, 1, 0], [0, 0, 0, 1, 1, 0, 1, 1, 1, 1], [0, 0, 1, 1, 0, 0, 1, 1, 1, 1], [0, 1, 0, 0, 0, 0, 0, 1, 1, 0], [0, 0, 0, 0, 0, 0, 1, 1, 0, 0], [1, 0, 1, 1, 1, 1, 0, 0, 0, 0]]
This is the output:
"' 0 0 0 0 0 0 0 0 0 0 1 1 0 1 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 1 1 0 0 0 0 0 0 1 1 1 0 0 0 0 1 1 0 1 1 1 1 0 0 1 1 0 0 1 1 1 1 0 1 0 0 0 0 0 1 1 0 0 0 0 0 0 0 1 1 0 0 1 0 1 1 1 1 0 0 0 0 '"
I'm encountering two problems:
There are stray " and ' which I can't get rid of
I have no idea how to do a newline
Simple way:
for row in list2D:
print " ".join(map(str,row))
Maybe join is appropriate for you:
print "\n".join(" ".join(str(el) for el in row) for row in ogm)
0 0 0 0 0 0 0 0 0 0
1 1 0 1 0 0 0 0 0 0
1 1 1 0 0 0 0 0 0 0
0 1 1 0 0 0 0 0 1 1
0 0 0 0 0 0 1 1 1 0
0 0 0 1 1 0 1 1 1 1
0 0 1 1 0 0 1 1 1 1
0 1 0 0 0 0 0 1 1 0
0 0 0 0 0 0 1 1 0 0
1 0 1 1 1 1 0 0 0 0
print "\n".join(" ".join(map(str, line)) for line in ogm)
If you want the rows and columns transposed
print "\n".join(" ".join(map(str, line)) for line in zip(*ogm))
for row in list2D:
print(*row)
To make the display even more readable you can use tabs or fill the cells with spaces to align the columns.
def printMatrix(matrix):
for lst in matrix:
for element in lst:
print(element, end="\t")
print("")
It will display
6 8 99
999 7 99
3 7 99
instead of
6 8 99
999 7 99
3 7 99
ogm = [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 1, 0, 1, 0, 0, 0, 0, 0, 0], [1, 1, 1, 0, 0, 0, 0, 0, 0, 0], [0, 1, 1, 0, 0, 0, 0, 0, 1, 1], [0, 0, 0, 0, 0, 0, 1, 1, 1, 0], [0, 0, 0, 1, 1, 0, 1, 1, 1, 1], [0, 0, 1, 1, 0, 0, 1, 1, 1, 1], [0, 1, 0, 0, 0, 0, 0, 1, 1, 0], [0, 0, 0, 0, 0, 0, 1, 1, 0, 0], [1, 0, 1, 1, 1, 1, 0, 0, 0, 0]]
s1 = str(ogm)
s2 = s1.replace('], [','\n')
s3 = s2.replace('[','')
s4 = s3.replace(']','')
s5= s4.replace(',','')
print s5
btw the " is actually two ' without any gap
i am learning python for a week. u guys have given some xcellent solutions. here is how i did it....this works too....... :)