I am trying to plot a histogram in Python with plt.hist. This is the array I would like to plot:
[162 162 162 161 162 157 162 161 164 161 163 160 155 162 160 154 162 162
163 160 162 157 162 160 165 161 162 161 155 163 161 155 162 162 162 161
163 156 163 160 165 161 163 161 154 162 160 155 163 163 163 161 162 156
162 160 165 161 162 160 154 163 161 155 163 162 163 160 163 157 163 161
165 161 162 160 155 162 160 155 164 164 159 155 161 159 158 160 161 161
155 159 154 154 156 155 160 160 163 158 160 163 159 156 159 162 156 163
155 154 156 152 158 158 154 156 158 158 156 157 158 160 160 159 153 152
153 150 154 155 158 158 159 160 156 157 163 157 158 159 159 155 156 157
154 155 157 158 155 154 155 157 160 154 154 157 157 157 156 153 157 156
156 161 157 155 154 153 159 158 157 157 158 155 159 154 156 156 156 158
159 155 150 148 158 159 156 157 157 155 157 158 158 158 157 156 157 153
159 156 160 156 158 156 156 153 156 156 157 157 157 157 160 157 156 156
159 155 154 158 156 155 154 160 158 158 159 155 155 158 158 156 155 156
151 158 157 156 156 155 158 158 159 157 155 158 157 154 157 157 157 159
155 156 154 156]
And this is my easy code:
hst = plt.hist(stego_histogram , bins=256)
plt.show()
This array is constructed with some pixels of a image. Obviously, 8-bit depth image has 256 values, that is why I choosed that bins. However, as this values goes from 148 to 165, the histogram return values from this range but divided into 256 values.
I have tried to configure the histogram with other bins values (16,17,18..) but it is never printed okay. This is the histogram with bins=18:
How can I plot this histogram correctly? I just want a bar histogram of this values. Thanks.
What histogram does is just count how many times a value repeats and then plots a vertical bar for every possible value, the height of each vertical bar is the number of occurrences of that value.
If you want the full histogram between 0 and 255 then you need to specify the parameter called range in the hist call.
Otherwise you could also use the bar method from matplotlib to just show the array you have provided here.
Here is the documentation for matplot bar
I really don't know why but with bins=17 everything is plotted okay. The issue was that intervals weren't integer as you can see in the graph that I attached. I tried this bins value before but it didn't works. Sorry and thanks for your answers!
What you need is not a histogram but a bar chart for the frequencies. The frequencies can be computed using Counter. In the below answer, replace data by your actual data list.
import matplotlib.pyplot as plt
from collections import Counter
data = [162, 162, 162, 161, 162, 157, 162, 159, 155, 155, 158, 158, 156]
freqs = Counter(data)
plt.bar(freqs.keys(), freqs.values())
plt.show()
IIUC, you want something like this:
counts, bins, _ = plt.hist(data, bins=range(256))
plt.show()
Output:
Related
My sql query returning me 141 rows and two columns and i want to plot them in a horizontal bar graph. While doing so the data's are overlapping each other. How i can make the graph crisp and clear.
On Y axis it will show the report name and in X axis it'll show their value. How i can achieve that?
import os
import cx_Oracle
import matplotlib.pyplot as plt
import numpy as np
reportid_count = []
count_ID = []
c = conn.cursor()
query = 'select distinct (LTRIM(REGEXP_SUBSTR(ID, '[0-9]{3,}'), '0')) as ReportID,count(ID) from dev_user.RECORD_TABLE group by ID'
c.execute(query)
#loop through the rows fetched and store the records as arrays.
for row in c:
reportid_count.append(row[0])
print(row[0])
count_ID.append(row[1])
print(row[1])
fig = plt.figure(figsize=(13.5, 5))
#plot the bar chart
plt.barh(reportid_count,count_ID)#,color=['red', 'blue', 'purple']
for i, v in enumerate(count_ID):
plt.text(v, i, str(v), color='blue', fontweight='bold')
plt.title('Report_Details')
plt.xlabel('Report Count')
plt.ylabel("Report ID's")
path = r"\\dev_server.com\View\Foldert\uidDocuments\Store_Img"
os.chdir(path)
plt.savefig(path + '\squares.png')
plt.show()
conn.close()
Sample Dataset-
Report 1 1200
Report 2 0
Report 3 0
Report 4 0
Report 5 0
Report 6 0
Report 7 0
Report 8 0
Report 9 0
Report 10 0
Report 11 0
Report 12 0
Report 13 0
Report 14 0
Report 15 0
Report 16 0
Report 17 0
Report 18 0
Report 19 0
Report 20 0
Report 21 0
Report 22 0
Report 23 1
Report 24 2
Report 25 3
Report 26 4
Report 27 5
Report 28 6
Report 29 100
Report 30 101
Report 31 102
Report 32 103
Report 33 104
Report 34 105
Report 35 106
Report 36 107
Report 37 108
Report 38 109
Report 39 110
Report 40 111
Report 41 112
Report 42 113
Report 43 114
Report 44 115
Report 45 116
Report 46 117
Report 47 118
Report 48 119
Report 49 120
Report 50 121
Report 51 122
Report 52 123
Report 53 124
Report 54 125
Report 55 126
Report 56 127
Report 57 128
Report 58 129
Report 59 130
Report 60 131
Report 61 132
Report 62 133
Report 63 134
Report 64 135
Report 65 136
Report 66 137
Report 67 138
Report 68 139
Report 69 140
Report 70 141
Report 71 142
Report 72 143
Report 73 144
Report 74 145
Report 75 146
Report 76 147
Report 77 148
Report 78 149
Report 79 150
Report 80 151
Report 81 152
Report 82 153
Report 83 154
Report 84 155
Report 85 156
Report 86 157
Report 87 158
Report 88 159
Report 89 160
Report 90 161
Report 91 162
Report 92 163
Report 93 164
Report 94 165
Report 95 166
Report 96 167
Report 97 168
Report 98 169
Report 99 170
Report 100 171
Report 101 172
Report 102 173
Report 103 174
Report 104 175
Report 105 176
Report 106 177
Report 107 178
Report 108 179
Report 109 180
Report 110 181
Report 111 182
Report 112 183
Report 113 184
Report 114 185
Report 115 186
Report 116 187
Report 117 188
Report 118 189
Report 119 190
Report 120 191
Report 121 192
Report 122 193
Report 123 194
Report 124 195
Report 125 196
Report 126 197
Report 127 198
Report 128 199
Report 129 200
Report 130 201
Report 131 202
Report 132 203
Report 133 204
Report 134 205
Report 135 206
Report 136 207
Report 137 208
Report 138 209
Report 139 210
Report 140 211
Report 141 212
Report 142 0
Report 143 0
Report 144 0
Report 145 0
Report 146 0
Report 147 0
Report 148 0
Report 149 0
Report 150 0
Report 151 0
Report 152 700
Report 153 701
Report 154 702
Report 155 703
Report 156 704
Report 157 705
Report 158 706
Report 159 707
Report 160 708
Report 161 709
Report 162 710
Report 163 711
Report 164 712
Report 165 713
Report 166 714
Report 167 715
Report 168 716
Report 169 717
Report 170 718
Report 171 719
Report 172 720
Report 173 721
Report 174 722
Report 175 723
Report 176 724
Report 177 725
Report 178 726
Report 179 727
Report 180 728
Report 181 729
Report 182 730
Report 183 731
Report 184 732
Report 185 733
Report 186 734
Report 187 735
Report 188 736
Report 189 737
Report 190 738
Report 191 739
Report 192 740
Report 193 741
Report 194 742
Report 195 743
Report 196 744
Report 197 745
Report 198 746
Report 199 747
Report 200 748
Report 201 749
Report 202 750
Report 203 751
Report 204 752
Report 205 753
Report 206 754
Report 207 755
Report 208 756
Report 209 757
Report 210 758
Report 211 759
Report 212 760
Report 213 761
Report 214 762
Report 215 763
Report 216 764
Report 217 765
Report 218 766
Report 219 767
Report 220 768
Report 221 769
Report 222 770
Report 223 771
Report 224 772
Report 225 773
Report 226 774
Report 227 775
Report 228 776
Report 229 777
Report 230 778
Report 231 779
Report 232 780
Report 233 781
Report 234 782
Report 235 0
Report 236 0
Report 237 1300
Report 238 1400
I have this loop which print each 10 numbers in line then move to next line
for i in range(100, 201):
if i % 10 == 0:
print(i)
else:
print(i, end=" ", )
and this the result:
100
101 102 103 104 105 106 107 108 109 110
111 112 113 114 115 116 117 118 119 120
121 122 123 124 125 126 127 128 129 130
131 132 133 134 135 136 137 138 139 140
141 142 143 144 145 146 147 148 149 150
151 152 153 154 155 156 157 158 159 160
161 162 163 164 165 166 167 168 169 170
171 172 173 174 175 176 177 178 179 180
181 182 183 184 185 186 187 188 189 190
191 192 193 194 195 196 197 198 199 200
it printing first number in line alone, but the want the opposite, the last number alone, something like this
100 101 102 103 104 105 106 107 108 109
110 111 112 113 114 115 116 117 118 119
120 121 122 123 124 125 126 127 128 129
130 131 132 133 134 135 136 137 138 139
140 141 142 143 144 145 146 147 148 149
150 151 152 153 154 155 156 157 158 159
160 161 162 163 164 165 166 167 168 169
170 171 172 173 174 175 176 177 178 179
180 181 182 183 184 185 186 187 188 189
190 191 192 193 194 195 196 197 198 199
200
You have the correct code. The only thing is that you are breaking at mod 0. You should break at mod 9.
for i in range(100, 201):
if i % 10 == 9:
print(i)
else:
print(i, end=" ", )
Try this:
for i in range(100, 201):
if (i + 1) % 10 == 0:
print(i)
else:
print(i, end=" ")
Well, 100 % 10 is equals to zero.
Which means it's going to print 100 in a line, and 101 in another line.
If you want the new line to start from 100 then all you have to do is to make the statement i % 10 == 0 a false statement. So you will have to add one to the 100.
so just try this code instead
for i in range(100, 201):
if (i+1) % 10 == 0:
print(i)
else:
print(i, end=" ", )
or you could try changing i % 10 == 0 to i % 10 == 9
What I Can Say By Seeing Your Code Is That You Are Using 2 Print Statements. One Inside The If Statement And One Inside Else Statement.
So What Python Compiler Is Doing There Is Printing New Line When Each If Statement Is True.
So When Your Iterating Number%10 Will Be Zero It Will Print That Number And Add A New Line, Because After Each Print Statement Python Do So.
And As You Have end=" " in Else Statement So It Is Printing The Number In Same Line When IF Statements Are False.
So What You Can Do Is:
You Can Use if (i+1)%10: instead of i % 10 == 0:
When Your Iterating Number's(i's) One's Place Will Be 9 (i.e. 109,119,etc) The If Statement Will Be True For That One, The Number Will Be Printed On The Same Line And Will Add A New Line After That.
I would like to take an image and change the scale of the image, while it is a numpy array.
I would like to do it with native NumPy functions w/o PIL, cv2, SciPy etc
now I have this:
from copy import copy
import numpy as np
from scipy import misc
img = misc.face() # racoon from SciPy(np.ndarray)
img2 = copy(img) # copy of racoon, because misc.face() is Descriptor(?)
img2.shape() # (768, 1024, 3)
Which I need shape = (3072, 4096, 3)
I can do it easy with Pillow
CONVERT_IMAGE = Image.fromarray(img.astype('uint8'), 'RGB')
CONVERT_IMAGE = CONVERT_IMAGE.resize((4096, 3072), Image.NEAREST)
IMAGE_AS_ARRAY = np.asarray(CONVERT_IMAGE)
IMAGE_AS_ARRAY.shape # 3072 4096 3
but I realy need to do this only with NumPy functions w/o other libs
Can you help me ? I'm really weak in NumPy and 3D-arrays
Limited to whole integer upscaling with some scaling factor n and without actual interpolation, you could use np.repeat twice to get the described result:
import numpy as np
# Original image with shape (4, 3, 3)
img = np.random.randint(0, 255, (4, 3, 3), dtype=np.uint8)
# Scaling factor for whole integer upscaling
n = 4
# Actual upscaling (results to some image with shape (16, 12, 3)
img_up = np.repeat(np.repeat(img, n, axis=0), n, axis=1)
# Outputs
print(img[:, :, 1], '\n')
print(img_up[:, :, 1])
Here's some output:
[[148 242 171]
[247 40 152]
[151 131 198]
[ 23 185 144]]
[[148 148 148 148 242 242 242 242 171 171 171 171]
[148 148 148 148 242 242 242 242 171 171 171 171]
[148 148 148 148 242 242 242 242 171 171 171 171]
[148 148 148 148 242 242 242 242 171 171 171 171]
[247 247 247 247 40 40 40 40 152 152 152 152]
[247 247 247 247 40 40 40 40 152 152 152 152]
[247 247 247 247 40 40 40 40 152 152 152 152]
[247 247 247 247 40 40 40 40 152 152 152 152]
[151 151 151 151 131 131 131 131 198 198 198 198]
[151 151 151 151 131 131 131 131 198 198 198 198]
[151 151 151 151 131 131 131 131 198 198 198 198]
[151 151 151 151 131 131 131 131 198 198 198 198]
[ 23 23 23 23 185 185 185 185 144 144 144 144]
[ 23 23 23 23 185 185 185 185 144 144 144 144]
[ 23 23 23 23 185 185 185 185 144 144 144 144]
[ 23 23 23 23 185 185 185 185 144 144 144 144]]
----------------------------------------
System information
----------------------------------------
Platform: Windows-10-10.0.16299-SP0
Python: 3.8.5
NumPy: 1.19.2
----------------------------------------
I'm learning python and am trying to learn about manipulating images. I want to rescale (downscale) a 2D graysacle image to a 1D vector (array of single row/column). In my test code, when I rescale the image, the output values in the array are in decimal (float) format. But I want to rescale and keep the values in the 1D array as integers. Can someone please help/guide me?
This is my code:
#Testing Image to vector
#Importing required functionality
import skimage.io as io
import numpy as np
from skimage.transform import rescale
#read image
image=io.imread("https://www.usna.edu/Users/cs/wcbrown/courses/F14IC210/lab/l09/cat.jpg")
#print image
print (image)
#rescale to 50%
small_im = rescale(image,0.5)
#print the rescaled image
print(small_im)
#manipulate the array
x=np.array(small_im)
#convert to 1D vector
y=np.concatenate(x)
print (y)
#print each value in the 1D vector in a new line. Just to see how far it would go
for i in y:
print (i, end='\n')
A snippet of the output I get is this(it goes way further due to the loop):
[[ 8 8 9 ... 12 11 11]
[ 8 8 9 ... 12 11 11]
[ 7 7 8 ... 12 11 11]
...
[ 5 5 5 ... 98 97 96]
[ 5 5 5 ... 98 97 97]
[ 5 5 5 ... 99 98 97]]
[[0.02745098 0.02941176 0.02941176 ... 0.04509804 0.04313725 0.04313725]
[0.0254902 0.0254902 0.0254902 ... 0.04509804 0.04313725 0.04313725]
[0.0254902 0.0254902 0.0254902 ... 0.04509804 0.04313725 0.04313725]
...
[0.01960784 0.01960784 0.01960784 ... 0.38039216 0.37843137 0.37647059]
[0.01960784 0.01960784 0.01960784 ... 0.38039216 0.37843137 0.37647059]
[0.01960784 0.01960784 0.01960784 ... 0.38039216 0.38039216 0.37843137]]
[0.02745098 0.02941176 0.02941176 ... 0.38039216 0.38039216 0.37843137]
0.027450980392156862
0.029411764705882575
0.029411764705882575
0.027450980392156862
0.03137254901960784
0.03529411764705882
0.03529411764705882
0.032352941176470695
0.03039215686274498
0.02941176470588213
0.030392156862744994
0.03431372549019597
0.03529411764705882
0.0392156862745098
0.0392156862745098
0.0392156862745098
0.0392156862745098
0.0392156862745098
0.043137254901960784
After trying and googling, I've found the answer. At least, in my context, it is what I was trying to achieve.
Solution code:
#solution to converting to 1D vector
#Importing required functionality
import numpy as np
from PIL import Image
#Opening Image and resizing to 10X10 for easy viewing
image_test = np.array(Image.open('1.png').resize((10,10))) #note: I used a local image
#print image
print (image_test)
#manipulate the array
x=np.array(image_test)
#convert to 1D vector
y=np.concatenate(x)
print (y)
#print each value in the 1D vector in a new line. Just to see how far it would go
for i in y:
print (i, end='\n')
Desired sample output (due to the loop it goes further):
[[ 48 52 72 96 96 99 81 71 68 47]
[ 52 85 133 149 168 175 157 116 70 46]
[ 54 129 170 174 185 179 177 169 92 42]
[ 55 142 165 171 187 175 162 167 97 40]
[112 150 144 134 172 157 128 143 129 113]
[162 166 166 158 166 164 154 163 157 155]
[105 166 185 174 170 165 175 179 140 81]
[ 35 113 199 170 147 145 174 181 83 32]
[ 46 65 179 183 160 153 166 155 71 37]
[ 47 58 169 178 170 159 148 158 74 39]]
[ 48 52 72 96 96 99 81 71 68 47 52 85 133 149 168 175 157 116
70 46 54 129 170 174 185 179 177 169 92 42 55 142 165 171 187 175
162 167 97 40 112 150 144 134 172 157 128 143 129 113 162 166 166 158
166 164 154 163 157 155 105 166 185 174 170 165 175 179 140 81 35 113
199 170 147 145 174 181 83 32 46 65 179 183 160 153 166 155 71 37
47 58 169 178 170 159 148 158 74 39]
48
52
72
96
96
99
81
71
68
47
52
85
133
149
168
175
157
116
70
46
I want to write a for loop in python which iterates for example like 111, 112, 113, 114, 121, 122, 123, 124, 131,.. up to 444. Is there an efficient way to do so?
I tried to convert between decimal and base 4 system but is there a better way to do so?
>>> from itertools import chain
>>> for k in chain.from_iterable(range(i+1, i+5) for i in range(110, 450, 10)):
... print(k)
...
111
112
113
114
121
122
123
124
131
132
133
134
141
142
.
.
.
423
424
431
432
433
434
441
442
443
444
SO like this:
[ i for i in range(111, 445) if '0' < str(i)[-1] < '5']
you can use:
[ i for i in range(111, 445) if 0< i%(i-i%10) <5]
You can convert a range of integers to base 4 using base_repr from numpy:
import numpy
for i in range(64):
print(int(numpy.base_repr(i, base=4)) + 111)
Output:
111
112
113
114
121
122
123
124
131
132
133
134
141
142
143
144
211
212
213
214
221
222
223
224
231
232
233
234
241
242
243
244
311
312
313
314
321
322
323
324
331
332
333
334
341
342
343
344
411
412
413
414
421
422
423
424
431
432
433
434
441
442
443
444