8000 savefig() as PNG get a different result than the image shown in ipython notebook(SVG probably) · Issue #5859 · matplotlib/matplotlib · GitHub
[go: up one dir, main page]

Skip to content

savefig() as PNG get a different result than the image shown in ipython notebook(SVG probably) #5859

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
gepcel opened this issue Jan 15, 2016 · 16 comments
Assignees

Comments

@gepcel
Copy link
Contributor
gepcel commented Jan 15, 2016

I'm using matplotlib to plot some images in ipython notebook. But after saving fig as PNG, I get a different image than the one shown in the notebook. I've come across this issue multiple times. Mostly savefig() lose the font info, but there maybe others. Can anyone take a look?

The code is as following:

%matplotlib inline
%config InlineBackend.figure_format = 'svg'

mpl.rcParams['font.sans-serif'] = 'SimHei'  #to render some Chinese character properly 

d = [19, 14, 8, 21, 17, 10, 16, 11, 8]
cmap=plt.get_cmap('Set1', 6)

fig = plt.figure(dpi=400)
for i, x in enumerate(d):
    plt.bar(i, x, color=cmap(i%3))

ax = gca()
xlim(-0.2, 9)
width = ax.patches[0].get_width()

ax.xaxis.set_minor_locator(FixedLocator(np.arange(9)+width/2))
ax.xaxis.set_minor_formatter(FixedFormatter(['合计', '鱼卵', '仔稚鱼']*3))
ax.xaxis.set_major_locator(FixedLocator(np.array([1, 4, 7])+width/2))
ax.xaxis.set_major_formatter(FixedFormatter(['2012年6月', '2013年6月', '2014年6月']))
ax.xaxis.set_tick_params(which='major', pad=17)
ax.xaxis.set_tick_params(which='both', tick1On=False, tick2On=False)
ax.yaxis.set_tick_params(which='both', tick1On=False, tick2On=False, label1On=False)

for r in ax.patches:
    h = r.get_height()
    ax.text(r.get_x()+w/2, h+0.4, int(h), ha='center', va='center')
legend(ax.patches[:3], ['合计', '鱼卵', '仔稚鱼'], loc='upper right')
plt.tight_layout()
fig.savefig('a.png', dpi=fig.dpi)

I got the fig as following in notebook:
image

And the 'a.png' from 'savefig()' is as following:
a

I'm doing some quick plot and formatting, using both 'pyplot' and 'pylab' sometimes, sorry for the dirty code.
Some backgroud:

Windows 10;
matplotlib  '1.5.1rc1'
python 3.4
ipython 3.2.1
matplotlibrc file is set as default

Some test:

1. Result of `fig.savefig('a.svg')` is the same as shown in notebook.
2. If manually edit the `matplotlibrc` as following, `savefig` get the same result as shown in notebook.

    font.family         : sans-serif
    font.sans-serif: SimHei
@tacaswell
Copy link
Member

To clairfy, if you edit matplotlibrc the png comes out correct?

@tacaswell tacaswell added this to the Critical bug fix release (1.5.2) milestone Jan 15, 2016
@gepcel
Copy link
Contributor Author
gepcel commented Jan 15, 2016

@tacaswell Double checked, Yes.

Change the two lines as said in matplotlibrc -> restarte the kernel -> remove the line mpl.rcParams['font.sans-serif'] = 'SimHei' #to render some Chinese character properly in the code.

Then I can get the same image both by savefig as PNG and the image shown in notebook.

@gepcel gepcel closed this as completed Jan 15, 2016
@gepcel gepcel reopened this Jan 15, 2016
@gepcel
Copy link
Contributor Author
gepcel commented Jan 15, 2016

Sorry, I misclosed the issue by clicking "Close and comment", I mean “Close the Preview and comment"

@gepcel
Copy link
Contributor Author
gepcel commented Jan 18, 2016

@tacaswell @pelson
As I said before, I'm not sure the font info missing is the only defference between the png file from fig.savefig('a.png') and the image shown in notebook. But I don't know they are relative or not. And I don't know the issue is in my system environment or matplotlib or cartopy. This is very frustrating. Can anybody help? Let me show by an example:

%matplotlib inline
%config InlineBackend.figure_format = 'svg'

import cartopy.crs as ccrs
from cartopy.mpl.ticker import LongitudeFormatter, LatitudeFormatter
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd

#prepare the data
data = pd.DataFrame(np.array([[123.5, 39.2, 0, 1, 2, 3, 4],
                              [123.5, 39.3, 5, 6, 0, 1, 2],
                              [121.5, 40.7, 3, 4, 5, 6, 0],
                              [121.5, 40.3, 1, 2, 3, 4, 5]]),
                    index=['D01', 'D02', 'D03', 'D04'],
                    columns=['x', 'y', 'g_3', 'g_4', 'g_5', 'g_6', 'g_7'])
labels = ['0', '0-0.5', '0.5-1', '1-2', '2-3', '3-4', '4-5']
groups = [data.groupby('g_'+str(i)) for i in [3, 5, 6, 4, 7]]

x0, x1, y0, y1 = extent = 121, 124, 38.8, 41.1
width = 5
height = width * (y1-y0)/(x1-x0)

# creating 3*2 maps. Actually I only need 5, but I don't how to do that while x&y 
# being both shared. So let's put a legend on the 6th one.
fig, axs = plt.subplots(3, 2, sharex=True, sharey=True, 
                        figsize=(width*2, height*3), 
                        dpi=300, subplot_kw={'projection': ccrs.PlateCarree()})
# for everymap
for i, ax in enumerate(axs.flatten()):
    #some settings of everymap
    ax.set_extent(extent)
    ax.set_xticks([122, 123], crs=ccrs.PlateCarree())
    ax.set_yticks([39, 40, 41], crs=ccrs.PlateCarree())
    ax.xaxis.set_major_formatter(LongitudeFormatter())
    ax.yaxis.set_major_formatter(LatitudeFormatter())
    [tick.label.set_fontsize(11) for tick in ax.yaxis.get_major_ticks()]
    [tick.label.set_fontsize(11) for tick in ax.xaxis.get_major_ticks()]

    #plot the point for the first 5th map
    if i < 5:
        for n, g in groups[i]:
            ax.scatter(g.x, g.y, s=10*n**2, c='k', transform=ccrs.PlateCarree())

# I need a legend for all 5 maps, let's put it on the 6th map
# I don't need to plot on the 6th map, so, I put it outside the extent
for n in range(len(labels)):
    ax.scatter(120, 38, s=10*n**2, c='k', transform=ccrs.PlateCarree(),
              label=labels[n])
ax.legend(loc='upper right', scatterpoints=1)
fig.tight_layout()
fig.savefig('a.png', dpi=300)

By running the code in notebook, I got an image shown as inline in notebook. I did a screen clipping. The image is as:
image

And the a.png file saved by fig.savefig('a.png', dpi=300) is as:
a

Difference:

  1. Of the a.png file, do notice that the first plot is not the same size as the others, and it isn't arange well.
  2. The scatter point of zero size (s=10*n**2 when n=0)
    • The image shown in the notebook, the scatter point of size s=0 also got a small black point. But since I've zoomed out the page to get a full clipping, it might not be seen. It is really there in my notebook.
    • The a.png file got no point of size zero, even zoomed in.

Besides those, what's the right way to do if I only need 3 or 5 (any odd number other than 1) axes? Because by my way, I have to erase the 6th axis in Photoshop and move the 6th's xaxis up to the 4th axis.

Please tell me if any more information is needede.
Thanks.

@mdboom mdboom self-assigned this May 16, 2016
@mdboom mdboom modified the milestones: 2.0.1 (next bug fix release), 1.5.2 (Critical bug fix release) May 16, 2016
@tacaswell
Copy link
Member

@gepcel Can you open a new issue for misplaced subplots?

@mdboom
Copy link
Member
mdboom commented May 16, 2016

Have you tried deleting your font cache in ~/.matplotlib or ~/.config/matplotlib? matplotlib may not be picking up the font.

@gepcel
Copy link
Contributor Author
gepcel commented May 17, 2016

@tacaswell yes, I can open a new issue for misplaced subplots tomorrow. I'll check if I can still produce this in my current environment.

Thanks for replying @mdboom . Tomorrow, I'll check that. It has been a long time.

@gepcel
Copy link
Contributor Author
gepcel commented May 22, 2016

@tacaswell I have opened a new issue about the misplaced subplots as #6457.

@gepcel
Copy link
Contributor Author
gepcel commented May 22, 2016

@mdboom.
Thanks for helping, it works.
I can still reproduce this after a very long time, even after a total reinstall of windows os.
And I have searched issues like #6326, and #4492.
Deleting the ~/.matplotlib works.

@gepcel
Copy link
Contributor Author
gepcel commented May 23, 2016

For me, "deleting the ~/.matplotlib" can solve my problem, I'm fine if anyone close this issue, or anyone still want to do something.

@Elgins
Copy link
Elgins commented Oct 14, 2016

@gepcel Hi, gepcel, I have the same puzzle with you, I am user Mac, the plt.show() display the image fine, but when I savefig() it went wrong whatever png or svg. I delete the cache file mentioned above but it still didn't work, could you show me more detial about how you solve this, many thks if you help me.

@tacaswell
Copy link
Member

This section of the docs http://matplotlib.org/devdocs/users/text_props.html#text-with-non-latin-glyphs maybe helpful here.

@Elgins
Copy link
Elgins commented Oct 16, 2016

Thank you very much, I have figure this problem out. For anyone who maybe count this, here is my suggestion: no matter Windows or Mac OS, just find the path that matplotlib use for font store, and replace the default font "Vera" with your right font.

@tacaswell
Copy link
Member

@Elgins Replacing the 'vera' files with your preferred font is an extremely bad idea.

@Elgins
Copy link
Elgins commented Oct 21, 2016

@tacaswell Yeah, I am not professional, this should be the last method to try:)

@QuLogic
Copy link
Member
QuLogic commented Feb 6, 2017

Reporter says this is working.

@QuLogic QuLogic closed this as completed Feb 6, 2017
@QuLogic QuLogic modified the milestones: unassigned, 2.0.1 (next bug fix release) Feb 6, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants
0