1

I am trying to develop a flask app that is using matplotlib.figure, apparently I can't use pyplot according to their own suggestions.

I was reading from this response and I was using ax.set_title("whatever", pad=20)

that is effectively changing the height of my titles, but makes no difference to the 4 main graphs (they stay in the same position), I used other suggested solutions like \n, but it seems that is not working.

This is part of my code, and I am also attaching how it looks:

    # figsize = width, height (inches)
    fig = Figure(figsize = (6,10))
    
    # subplot(filas, columnas, index)
    ax1 = fig.add_subplot(4, 1, 1)
    ax1.plot(tiempo, data[0])
    ax1.set_title('Canal 1')
    ax1.set_xlabel('tiempo (s)')
    ax1.set_ylabel('g\'s')
    
    ax2 = fig.add_subplot(4, 1, 2)
    ax2.plot(tiempo, data[1])
    ax2.set_title('Canal 2')
    ax2.set_xlabel('tiempo (s)')
    ax2.set_ylabel('g\'s')
    
    ax3 = fig.add_subplot(4, 1, 3)
    ax3.plot(tiempo, data[2])
    ax3.set_title('Canal 3')
    ax3.set_xlabel('tiempo (s)')
    ax3.set_ylabel('g\'s')
    
    ax4 = fig.add_subplot(4, 1, 4)
    ax4.plot(tiempo, data[3])
    ax4.set_title('Canal 4')
    ax4.set_xlabel('tiempo (s)')
    ax4.set_ylabel('g\'s')


    # Saving figure to the buffer
    buf = BytesIO()
    fig.savefig(buf, format = 'png')
    image = base64.b64encode(buf.getbuffer()).decode("utf8")     
    return jsonify({'status': True, 'image': image})

this is the overlapping figure

Looked in many different places, but most solutions are for pyplot. Does anybody knows how to do this?

Eduardo
  • 45
  • 9

1 Answers1

2

So I ran your code and got the same result with overlapping titles and labels.

import matplotlib.pyplot as plt
import io
import base64

tiempo = [1,2,3,4,5,6,7,8,9]
data = [9,8,7,6,5,4,3,2,1]

# figsize = width, height (inches)
fig = plt.figure(figsize=(6, 10))

# subplot(filas, columnas, index)
ax1 = fig.add_subplot(4, 1, 1)
ax1.plot(tiempo, data)
ax1.set_title('Canal 1')
ax1.set_xlabel('tiempo (s)')
ax1.set_ylabel('g\'s')

ax2 = fig.add_subplot(4, 1, 2)
ax2.plot(tiempo, data)
ax2.set_title('Canal 2')
ax2.set_xlabel('tiempo (s)')
ax2.set_ylabel('g\'s')

ax3 = fig.add_subplot(4, 1, 3)
ax3.plot(tiempo, data)
ax3.set_title('Canal 3')
ax3.set_xlabel('tiempo (s)')
ax3.set_ylabel('g\'s')

ax4 = fig.add_subplot(4, 1, 4)
ax4.plot(tiempo, data)
ax4.set_title('Canal 4')
ax4.set_xlabel('tiempo (s)')
ax4.set_ylabel('g\'s')

# Saving figure to the buffer
buf = io.BytesIO()
fig.savefig(buf, format='png')
plt.show()

Overlapping layout

However, matplotlib has this handy function called tight_layout() which automatically adjusts padding between and around subplots which you should call before saving or showing the plot figure.

# Saving figure to the buffer
buf = io.BytesIO()
fig.savefig(buf, format='png')
plt.tight_layout()
plt.show()

This results in a figure with padding between each plot.

Fixed layout

Adilius
  • 308
  • 2
  • 10
  • 1
    That's excellent, @adilius, but you are using pyplot which is not recommended for flask according to their own [documentation](https://matplotlib.org/devdocs/gallery/user_interfaces/web_application_server_sgskip.html)... I have seen some posts where users are working with pyplot in flask and closing it after. I guess that's another option; using it, and then closing it to prevent memory leaks. – Eduardo Sep 12 '21 at 13:40