blz - 1 year ago 71

Python Question

I'm trying to make a special kind of grating called a Gabor patch, an example of which can be found at the bottom of this tutorial whose code I ported to python.

Using matplotlib's

`imshow`

While the coloring is different, I suspect that this has to do with how matplotlib displays numerical values. In essence, this image is a 2D, 100-by-100 pixel array containing values from

`-1.0`

`1.0`

- The coloring is converted to grayscale coloring (
*c.f.*: the last image in the first link) - The solution must employ pygame version . For some inexplicable reason, I can't find a way to install
`1.9.1release`

on my OS (Ubuntu 13.04). There appear to be no PPAs and pygame is evidently not on PIP.`1.9.2`

Thank you very much in advance, and please let me know if I can provide additional information!

Regarding @Veedrac's solution (which is remarkably similar to my own), here is what my patch looks like when using the grayscale colormap in matplotlib's

`imshow`

`from matplotlib.pyplot import *`

import matplotlib.cm as cm

figure()

imshow(g, cm=cm.Greys_r)

show()

Answer Source

```
import numpy
import pickle
import pygame
surface = pygame.Surface((100, 100))
```

Get the pixels, convert to RGBA. Using Joe Kington's reminder that the data ranges from -1 to 1:

```
base = (pickle.load(open("g.pickle"))+1)/2 * 255
base = base[..., numpy.newaxis].repeat(4, -1).astype("uint8")
```

Copy the data across

```
numpy_surface = numpy.frombuffer(surface.get_buffer())
numpy_surface[...] = numpy.frombuffer(base)
del numpy_surface
```

Show it with:

```
screen = pygame.display.set_mode((100, 100))
screen.blit(surface, (0, 0))
pygame.display.flip()
```

and you get

And simplified, once again thanks to Joe Kington's input, using `make_surface`

:

```
import numpy
import pickle
import pygame
base = (pickle.load(open("g.pickle"))+1) * 128
base = base[..., None].repeat(3, -1).astype("uint8")
surface = pygame.surfarray.make_surface(base)
screen = pygame.display.set_mode((100, 100))
screen.blit(surface, (0, 0))
pygame.display.flip()
```

The `base[..., None]`

is normally spelt `base[..., numpy.newaxis]`

, but seeing as that was the only instance of `numpy`

I just "expanded the constant" so as to not need `numpy`

. It didn't work, though, as the code breaks if you don't import `numpy`

with a `IndexError: bytes to write exceed buffer size`

. Thanks, `numpy`

.

The `...`

means "the whole of all of the axis before this point", so you can replace `[3:2]`

, `[:, 3:2]`

and `[:, :, :, 3:2]`

with `[..., 3:2]`

. In fact, `...`

was introduced to Python for this very reason.

The `None`

, or `numpy.newaxis`

, slices a new axis (duh). This will transform `[a, b, c]`

into `[[a], [b], [c]]`

, for example. This is needed because we then `repeat`

along this new axis.

Basically, looking at one row, we have

```
114, 202, 143, ...
```

and we want

```
[114, 114, 114], [202, 202, 202], [143, 143, 143], ...
```

so our `[..., None]`

got us to

```
[114], [202], [143], ...
```

and we just `repeat`

`3`

times in axis `-1`

. Axis `-1`

is, of course, the last axis, which is the `numpy.newaxis`

.