Vitaly Davydov
Vitaly Davydov

Reputation: 108

matplotlib render image with specs (size, alligment etc.) in pixels

I have specs for a mockup, for example, Photoshop/Illustrator/Sketch file with each elements specifications like size, position, and coordinates in pixels.

An image looks like:

enter image description here

I can draw similar image just using standard matplotlib technic without any problems.

The question is, how to render an image exactly with its specs? All sizes, font sizes, alignments, should be the same as in the specs (as it's drawn in Illustrator).

I've researched over matplotlib docs, but even transformers tutorial doesn't help.

Update with an exact example.

I have a mock at Zeplin which shows coordinated of each plot (Image is also a plot here). So I know, that the image has margins 25x25px from a border and its size is 80x80 pixels.

this is mock image (again not allowed to embed the image).

How would you do that?

The code I use for drawing

fig, ax = plt.subplots(1, 2, figsize=(20, 10), sharey=True)

recs = ax[0].barh(y_pos, widths, align='edge');

img = mpimg.imread('/Users/iwitaly/Downloads/2017-11-12 17.40.46.jpg')

ax[0].spines['left'].set_visible(False);
ax[0].spines['right'].set_visible(False);
ax[0].spines['bottom'].set_visible(False);
ax[0].spines['top'].set_visible(False);

ax[0].get_xaxis().set_visible(True);
ax[0].get_yaxis().set_visible(True);


obj = ax[0].text(x=0, y=3.9, s=r'Name: Vitaly Davydov',
          fontsize=30, fontname="Courier New", weight='bold');

ax[0].axhline(y=3.85, xmin=0, xmax=0.75, color='black');

# I'd like to place axicon exactly with 25x25 marging from top left corner
axicon = fig.add_axes([0.08, 1, 0.2, 0.2], transform=None)
axicon.axis('off');
axicon.imshow(img, interpolation='none');


for i, r in enumerate(recs):
    r.set_color(index_to_color[i]);
    r.set_height(col_wight);
    ax[0].text(x=0, y=text_positions[i], s=index_to_text[i], fontsize=30, fontname="Courier New");


ax[1].spines['left'].set_visible(False);    
ax[1].spines['right'].set_visible(False);
ax[1].spines['bottom'].set_visible(False);
ax[1].spines['top'].set_visible(False);

ax[1].get_xaxis().set_visible(False);
ax[1].get_yaxis().set_visible(False);


ax[1].text(x=0, y=3.9, s='Increment:', fontsize=30,
           fontname="Courier New", weight='bold');

ax[1].axhline(y=3.85, xmin=0, xmax=0.4, color='black');

for i, r in enumerate(recs):
    text_x, text_y = r.xy

    increment_pos_y = text_y + col_wight / 2
    if increment_values[i] > 0:        
        increment_text = '+{}'.format(increment_values[i])
    elif increment_values[i] < 0:
        increment_text = '-{}'.format(increment_values[i])
    else:
        increment_text = '{}'.format(increment_values[i])


    ax[1].text(x=0, y=increment_pos_y, s=increment_text,
               fontsize=30, color=index_to_color[i],
               fontname="Courier New", weight='bold');  

In this example I'd like to place axicon axes that is an image with 25x25 margin and 80x80 size (all in pixels).

Upvotes: 0

Views: 355

Answers (1)

ImportanceOfBeingErnest
ImportanceOfBeingErnest

Reputation: 339660

To place an axes to the figure, you can use fig.add_axes([left, bottom, width, height]), where left, bottom, width, height are fractions of the figure size.

To convert from pixels to fraction of figure size, you need to divide the pixels by the figure dpi and the figure size. E.g. for the left edge

left = 25/fig.dpi/fig.get_size_inches()[0]

Complete example:

import matplotlib.pyplot as plt
import numpy as np

fig, ax = plt.subplots(1, 2, figsize=(10, 7))
y_pos, widths = np.linspace(0,3,4), np.random.rand(4)
recs = ax[0].barh(y_pos, widths, align='edge');

#img = plt.imread('/Users/iwitaly/Downloads/2017-11-12 17.40.46.jpg')
img = np.random.rand(80,80)

# I'd like to place axicon exactly with 25x25 marging from top left corner
x,y= 25,25 #pixels
dx,dy = 80,80
w,h = fig.get_size_inches()
axicon = fig.add_axes([x/float(fig.dpi)/w, 1.-(y+dy)/float(fig.dpi)/h, 
                       dx/float(fig.dpi)/w, dy/float(fig.dpi)/h])
axicon.axis('off');
axicon.imshow(img, interpolation='none');

plt.show()

Upvotes: 1

Related Questions