0

I have a .jpg image with dimensions 440x219.

Original .jpg image

I use Matplotlib to make a surface plot of this image which seems to be working fine resulting in:

Matplotlib rendered image

However, you can see that the squares got deformed into rectangles. My question is: how can I let Matplotlib render these images as squares instead (like in the original .jpg) image.

The code that I'm currently using to render:

 fig = plt.figure(figsize=(5, 4))
 ax = plt.axes(projection='3d')
 ax.plot_surface(X, Y, img_binary, rstride=1, cstride=1, linewidth=0, cmap='gray')

 ax.view_init(40, -20)
 plt.show()

I'm assuming there must be some option available for this. Any pointers would be appreciated.

1 Answers1

0

https://stackoverflow.com/a/64453375/21260084 answered the more general question of how to set the aspect ratio of Axis3d and the solution they propose works fine. Adapted to your context:

import matplotlib.pyplot as plt
import numpy as np

img = plt.imread('/tmp/ex.jpg')
fig = plt.figure(figsize=(5, 4))
ax = plt.axes(projection='3d')

xx, yy = np.mgrid[:img.shape[0], :img.shape[1]]
ax.plot_surface(xx, yy, img, rstride=1, cstride=1, linewidth=0, cmap='gray')
scale_height= 1.0
ax.set_box_aspect((img.shape[0], img.shape[1], np.ptp(img)*scale_height))

ax.view_init(40, -20)
plt.show()

3d surface plot rendering of image

Note that you also want to/have to scale the third dimension w.r.t. the other ones. The example sets 1 pixel equal to a change of one in the range of the grayscale image, but what you actually want obviously depends on the context.

v4hn
  • 41
  • 5