Skip to content

Too small axis arrow when savefig to png #7489

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
AndreWin opened this issue Nov 20, 2016 · 13 comments
Closed

Too small axis arrow when savefig to png #7489

AndreWin opened this issue Nov 20, 2016 · 13 comments
Assignees
Milestone

Comments

@AndreWin
Copy link

Hello!

My code:

import matplotlib as mpl
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid.axislines import SubplotZero

fig = plt.figure()
ax = SubplotZero(fig, 111)
_ = fig.add_subplot(ax)

for direction in ["xzero", "yzero"]:
    ax.axis[direction].set_visible(True)
    ax.axis[direction].set_axisline_style("->")
for direction in ["top", "bottom", "left", "right"]:
    ax.axis[direction].set_visible(False)
ax.axis["yzero"].set_axis_direction("left")
ax.grid(True)
ax.minorticks_on()

plt.plot([0,1], [0,1], c="blue", lw=2)
_ = plt.title("График")
_ = plt.xlabel("Ось x")
_ = plt.ylabel("Ось y")

for ext in ['png', 'svg', 'pdf']:
    plt.savefig("test_chart."+ext)
plt.show()
plt.close()

My matplotlibrc file in MPLCONFIGDIR:

xtick.labelsize: 14.0  
ytick.labelsize: 14.0  
axes.titlesize: 20.0   
axes.labelsize: 16     
legend.fontsize: 12    
axes.grid: True        
font.family: Roboto   # I copied roboto font to matplotlib font folder
font.style: italic
font.size: 14 
figure.figsize: 12, 8 

savefig.dpi: 300 
savefig.format: png
savefig.bbox: tight 

animation.writer : ffmpeg_file
animation.ffmpeg_path: ffmpeg 
animation.codec: h264 
# animation.html : html5 

I works on Windows 8.1 64bit. I use Python 3.5.2 |Continuum Analytics, Inc.| (default, Jul 5 2016, 11:41:13) [MSC v.1900 64 bit (AMD64)] on win32 in environmet, created with conda.
Matplotlib version is 1.5.3

When I see files created with matplotlib I see that arrows on axis ends are normal in svg and pdf files but too small in png file.

In svg file:

arrow_on_svg

In png file:

arrow_on_png

Maybe it's bug.

Best regards, Andrey.

@AndreWin
Copy link
Author

AndreWin commented Nov 20, 2016

I also noticed that these arrows are small when use show() too.
I tried this in jupyter notebook, that I installed via pip in virtual environment created with conda.

@afvincent
Copy link
Contributor

afvincent commented Nov 20, 2016

I think it is the same bug as in issue #6035 (the size of the arrow head depends on the DPI value) , so it should be fixed for mpl 2 (PR #6504), but I am not sure the fix was backported to the 1.5 branch.
If you have access to the latest beta version of mpl (2.0.4), you might want to give it a try.

@AndreWin
Copy link
Author

@afvincent, I will try beta soon and will give answer. Thanks.

@afvincent afvincent self-assigned this Dec 9, 2016
@afvincent
Copy link
Contributor

@AndreWin Did you have the opportunity to check with the new RC1 of matplotlib 2.0? It seems to me that the problem of the DPI-dependent arrow head size is not present anymore.

However, during my own tests with RC1, the tick direction was not outward (but there is an easy fix for that) and the grid behavior was weird:
test_chart

Here is a possible workaround:

# -*- coding: utf-8 -*-

import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid.axislines import SubplotZero

fig = plt.figure()
ax = SubplotZero(fig, 111)
_ = fig.add_subplot(ax)

for direction in ["xzero", "yzero"]:
    ax.axis[direction].set_visible(True)
    ax.axis[direction].set_axisline_style("->")
    # Set outward ticks
    ax.axis[direction].major_ticks.set_tick_out(True)
    ax.axis[direction].minor_ticks.set_tick_out(True)

for direction in ["top", "bottom", "left", "right"]:
    ax.axis[direction].set_visible(False)
ax.axis["yzero"].set_axis_direction("left")

plt.plot([0,1], [0,1], c="blue", lw=2)
_ = plt.title(u"График")
_ = plt.xlabel(u"Ось x")
_ = plt.ylabel(u"Ось y")

ax.minorticks_on()

# Workaround: as ax.grid(True) seems to be buggy, manually create a custom grid
# 1- Set the desired lower bound for each axis (here 0.0)
xlims = [0.0, ax.get_xlim()[1]]
ylims = [0.0, ax.get_ylim()[1]]
# 2- For each axis, get the (major) relevant tick locations
#    and draw a collection of lines
grid_style = dict(color='Black', lw=0.5, linestyles=':')  # 1.5.3-like style
xticks = [val for val in ax.xaxis.get_ticklocs() if xlims[0] < val <= xlims[1]]
ax.vlines(xticks, ymin=ylims[0], ymax=ylims[1], **grid_style)
yticks = [val for val in ax.yaxis.get_ticklocs() if ylims[0] < val <= ylims[1]]
ax.hlines(yticks, xmin=xlims[0], xmax=xlims[1], **grid_style)

for ext in ['png', 'svg', 'pdf']:
    plt.savefig("workaround_test_chart."+ext, dpi=300)
plt.show()

workaround_test_chart

@AndreWin
Copy link
Author

Hello, @afvincent. Sorry that didn't answer for a long time. I didn't find how to install beta version of maptlotlib in my environment created with conda.
Thank you very much for workarrond! :)
Best regards, Andrey.

@tacaswell
Copy link
Member

@AndreWin http://matplotlib.org/style_changes.html (link in the banner on the top of all matplotlib.org pages now).

@AndreWin
Copy link
Author

@tacaswell, many thanks :)
I'll try it now.

@AndreWin
Copy link
Author

End of arrows works now (version 2.0.0rc1). But I try to understand, why in my code

_ = plt.xlabel("Ось x")
_ = plt.ylabel("Ось y")

but I see "Ось x" on vertical axis... O_o

image

Full code is in my first message here.

Best regards, Andrey.

@tacaswell
Copy link
Member

I can reproduce the xlabel/ylabel issue, I suspect there is a bug in from mpl_toolkits.axes_grid.axislines import SubplotZero but I have not tracked it down. I can not reproduce this xlabel/ylabel issue with fig, ax = plt.subplots() source Axes objects.

As a side note, the default font supports Cyrillic out of the box in 2.0.

@QuLogic
Copy link
Member

QuLogic commented Dec 12, 2016

I'm not sure if this is expected when using SubplotZero, but you can use:

ax.axis['xzero'].set_label("Ось x")
ax.axis['yzero'].set_label("Ось y")

to get the correct labels.

@AndreWin
Copy link
Author

@tacaswell, when I replaced

fig = plt.figure()
ax = SubplotZero(fig, 111)
_ = fig.add_subplot(ax)

to

fig, ax = plt.subplots()

I got error TypeError: 'method' object is not subscriptable on line

ax.axis[direction].set_visible(True)

Full code:

# fig = plt.figure()
# ax = SubplotZero(fig, 111)
# _ = fig.add_subplot(ax)
fig, ax = plt.subplots()

for direction in ["xzero", "yzero"]:
    ax.axis[direction].set_visible(True)
    ax.axis[direction].set_axisline_style("->")
for direction in ["top", "bottom", "left", "right"]:
    ax.axis[direction].set_visible(False)
ax.axis["yzero"].set_axis_direction("left")
ax.grid(True)
ax.minorticks_on()

plt.plot([0,1], [0,1], c="blue", lw=2)
_ = plt.title("График")
_ = plt.xlabel("Ось x")
_ = plt.ylabel("Ось y")
# ax.axis['xzero'].set_label("Ось x")
# ax.axis['yzero'].set_label("Ось y")

for ext in ['png', 'svg', 'pdf']:
    plt.savefig("test_chart."+ext)
plt.show()
plt.close()

the default font supports Cyrillic out of the box in 2.0.

Really? Cool!!!! ^_^

@AndreWin
Copy link
Author

@QuLogic, your workaround works nice! Many thanks! :)

@tacaswell
Copy link
Member

Closing as fixed in 2.0, but created a new issue to track the SubplotZero axis not being labeled correctly.

See http://matplotlib.org/2.0.0rc1/users/dflt_style_changes.html#normal-text re the font.

@QuLogic QuLogic added this to the 2.0 (style change major release) milestone Dec 12, 2016
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

4 participants