Skip to content
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

Aspect on semi-log plots #996

Open
vascotenner opened this issue Nov 30, 2016 · 12 comments
Open

Aspect on semi-log plots #996

vascotenner opened this issue Nov 30, 2016 · 12 comments
Assignees
Labels
tag: backend: mpl type: bug Something isn't correct or isn't working
Milestone

Comments

@vascotenner
Copy link
Contributor

The aspect parameter can be used to set the aspect of a plot:

%%opts Curve [ aspect=2]
hv.Curve((np.linspace(0.1,10 )))

download

However, when setting one of the axis to log, the aspect parameter is ignored:

%%opts Curve [logy=True, aspect=2]
hv.Curve((np.linspace(0.1,10 ),np.linspace(0.1,100 )))

download 1

@philippjfr philippjfr added type: bug Something isn't correct or isn't working tag: backend: mpl labels Nov 30, 2016
@philippjfr
Copy link
Member

I've noticed this as well and haven't yet been able to figure out what's going on here. Presumeably this expression doesn't work correctly with log axes:

axes.set_aspect(((1./axes.get_data_ratio()))/aspect)

@vascotenner
Copy link
Contributor Author

When running for the first time, this warning appears:

/usr/local/lib/python2.7/dist-packages/matplotlib/axes/_base.py:1166: UserWarning: aspect is not supported for Axes with xscale=linear, yscale=log
  'yscale=%s' % (xscale, yscale))

@philippjfr
Copy link
Member

philippjfr commented Jan 10, 2017

Thanks, wonder what the correct way of setting log-linear plot aspects is then.

@vascotenner
Copy link
Contributor Author

A solution inspired from stackoverflow answer:

def fixed_aspect_ratio_loglog(plot, element):
    '''
    Set a fixed aspect ratio on matplotlib loglog plots 
    regardless of axis units
    '''
    ratio = plot._aspect_param_value
    ax = plot.handles['axis']
    xvals,yvals = ax.axes.get_xlim(),ax.axes.get_ylim()

    xrange = np.log(xvals[1])-np.log(xvals[0])
    yrange = np.log(yvals[1])-np.log(yvals[0])
    ax.set_aspect(ratio*(xrange/yrange), adjustable='box')
%%opts Curve [logx=True, logy=True, aspect=1, final_hooks=[fixed_aspect_ratio_loglog_hv]]
hv.Curve((np.linspace(1,10,10), np.linspace(1,10,10)**10))

download

@philippjfr philippjfr self-assigned this Jan 16, 2017
@philippjfr
Copy link
Member

Assigned myself, will look into it.

@thoth291
Copy link
Contributor

thoth291 commented Mar 9, 2017

Hi, @philippjfr .

I'm sorry for bothering.

Any progress on this?

I did this

import numpy as np
def fixed_aspect_ratio_loglog(plot, element):
    '''
    Set a fixed aspect ratio on matplotlib loglog plots 
    regardless of axis units
    '''
    ratio = plot.aspect
    ax = plot.handles['axis']
    xvals,yvals = ax.axes.get_xlim(),ax.axes.get_ylim()
    print xvals,yvals
    xrange=xvals[1]-xvals[0]
    #if ax.get_xaxis().get_scale()=='log':#or linear 
    if plot.logx:
        xrange = np.log(xvals[1])-np.log(xvals[0])
    yrange=yvals[1]-yvals[0]
    #if plot._logy_param_value:
    #if ax.get_yaxis().get_scale()=='log':
    if plot.logy:
        yrange = np.log(yvals[1])-np.log(yvals[0])
    print ax.get_aspect()
    print xrange,yrange,ratio
    ax.set_aspect(ratio*(xrange/yrange), adjustable='box')
    print ax.get_aspect()


plot=curve(plot=dict(logx=True,aspect=1,final_hooks=[fixed_aspect_ratio_loglog]),style=dict(width=800,height=600))
plot

And got this

(0.0001, 10.0) (0.0, 89.086297565778608)
auto
11.512925465 89.0862975658 1
0.129233403784

And these warnings:

.../matplotlib/axes/_base.py:1292: UnicodeWarning: Unicode equal comparison failed to convert both arguments to Unicode - interpreting them as being unequal
  if aspect == 'normal':
.../matplotlib/axes/_base.py:1297: UnicodeWarning: Unicode equal comparison failed to convert both arguments to Unicode - interpreting them as being unequal
  elif aspect in ('equal', 'auto'):
.../matplotlib/axes/_base.py:1404: UserWarning: aspect is not supported for Axes with xscale=log, yscale=linear
  'yscale=%s' % (xscale, yscale))

The image is still square:
image

Thank you for your help!

@thoth291
Copy link
Contributor

thoth291 commented Mar 9, 2017

Here is what I'm actually trying to do but implemented in matplotlib:

%matplotlib inline
from matplotlib import pyplot as plt
plt.figure(figsize=(20,10))
plt.semilogx(times, freqs)
plt.title('all of them')
plt.grid(True)

image

@philippjfr philippjfr added this to the v1.7.0 milestone Mar 9, 2017
@philippjfr philippjfr changed the title aspect and log plots Aspect on semi-log plots Mar 16, 2017
@philippjfr
Copy link
Member

Keeping this open, we have a fix for loglog plots now, but not semilog.

@philippjfr philippjfr modified the milestones: v2.0, v1.7.0 Mar 16, 2017
@NGillet
Copy link

NGillet commented Nov 15, 2018

A temporary solution is to set the figure size to force it to be square:

fig, ax = plt.subplots(  )
ax.set_yscale("log", nonposy='clip')
...
fig_size = fig.get_size_inches()
fig.set_size_inches( fig_size[1]*1.1, fig_size[1]*1.1 )

the 1.1 scaling is for avoiding cuts in the labels, should be adapted for case to case.

@seanysull
Copy link

I have a log scale on my y-axis and wish to stretch out the x-axis, is there a workaround for achieving this?

@rabernat
Copy link

Just hit this issue. Would be great to see a fix.

@jadolfbr
Copy link

jadolfbr commented Sep 26, 2019

@philippjfr - You say you have a fix for loglog plots, but I still cannot get an equal aspect ratio for them. Anytime I attempt to set it - it squishes the X axis while elongating the y axis. Otherwise, its pretty much the opposite.

plt.scatter(n_data[x_group], n_data[y_group], marker='D', s=23) 

axes = plt.gca()
axes.set_xlim([min_x,max_x])
axes.set_ylim([min_y,max_y])

plt.plot([min_x, max_x], [min_y, max_y], 'k-')
plt.loglog()
plt.gca().set_aspect('equal', adjustable='box')

Results in something like this:

image

Am I doing something inherently wrong with trying to get an equal aspect ratio? Is there any workaround? I've also tried setting the xscale and yscale to logs, same thing.

Similar code, but for non log/log gives something like this:
image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
tag: backend: mpl type: bug Something isn't correct or isn't working
Projects
None yet
Development

No branches or pull requests

7 participants