Bug in axhline

Hello,

I think the following is'nt right:

In [1]: plot([1,2,3])
Out[1]: [<matplotlib.lines.Line2D object at 0x8f9b0ec>]

In [2]: ylim(-4,4)
Out[2]: (-4, 4)

In [3]: axhline()
Out[3]: <matplotlib.lines.Line2D object at 0x8f9bc0c>

In [4]: ylim()
Out[4]: (0.0, 3.0)

By,

  Friedrich

With the attached patch the thinks are ok:

In [1]: plot([1,2,3])
Out[1]: [<matplotlib.lines.Line2D object at 0x8f9b0ac>]

In [2]: ylim(-4,4)
Out[2]: (-4, 4)

In [3]: xlim(-4,4)
Out[3]: (-4, 4)

In [4]: axhline()
Out[4]: <matplotlib.lines.Line2D object at 0x8fa6e6c>

In [5]: axvline()
Out[5]: <matplotlib.lines.Line2D object at 0x9062fec>

In [6]: xlim()
Out[6]: (-4.0, 4.0)

In [7]: ylim()
Out[7]: (-4.0, 4.0)

By,

  Friedrich

axline.patch (1.08 KB)

···

On Thu, May 15, 2008 at 10:20:23AM +0200, Friedrich Hagedorn wrote:

Hello,

I think the following is'nt right:

In [1]: plot([1,2,3])
Out[1]: [<matplotlib.lines.Line2D object at 0x8f9b0ec>]

In [2]: ylim(-4,4)
Out[2]: (-4, 4)

In [3]: axhline()
Out[3]: <matplotlib.lines.Line2D object at 0x8f9bc0c>

In [4]: ylim()
Out[4]: (0.0, 3.0)

While I agree the behavior here is not optimal, I don't think the fix
is right. axhline already tells the axes not to autoscale in the x
direction, as it should

l, = self.plot([xmin,xmax], [y,y], transform=trans, scalex=False, **kwargs)

so I don't think automatically forcing the autoscale off entirely for
x and y as in your patch is what we want in general. For example,
consider this case

plot([1,2,3])
ylim(-4,4)
axhline(20)

What we want is to autoscale only if autoscale_on=True *and* the hline
is outside the current bounds. Something like:

        ymin, ymax = self.get_ylim()
        if ymax<ymin: ymin, ymax = ymax, ymin
        scaley = (y<ymin) or (y>ymax)

        trans = mtransforms.blended_transform_factory(
            self.transAxes, self.transData)
        l, = self.plot([xmin,xmax], [y,y], transform=trans,
scalex=False, scaley=scaley, **kwargs)

I just committed this to svn in r5141 so give it a test drive and let
me know what you think.

There is an unrelated problem with the autoscaler which is that in the example

plot([1,2,3])
axhline(20)

it sets ymax to 20 making the hline invisible. We should probably
force the ylimits to be strictly outside the data limits in some cases
when autoscaling.
JDH

···

On Thu, May 15, 2008 at 3:41 AM, Friedrich Hagedorn <friedrich_h@...380...> wrote:

On Thu, May 15, 2008 at 10:20:23AM +0200, Friedrich Hagedorn wrote:

Hello,

I think the following is'nt right:

In [1]: plot([1,2,3])
Out[1]: [<matplotlib.lines.Line2D object at 0x8f9b0ec>]

In [2]: ylim(-4,4)
Out[2]: (-4, 4)

In [3]: axhline()
Out[3]: <matplotlib.lines.Line2D object at 0x8f9bc0c>

>> Hello,
>>
>> I think the following is'nt right:
>>
>> In [1]: plot([1,2,3])
>> Out[1]: [<matplotlib.lines.Line2D object at 0x8f9b0ec>]
>>
>> In [2]: ylim(-4,4)
>> Out[2]: (-4, 4)
>>
>> In [3]: axhline()
>> Out[3]: <matplotlib.lines.Line2D object at 0x8f9bc0c>

[...]

For example, consider this case

plot([1,2,3])
ylim(-4,4)
axhline(20)

What we want is to autoscale only if autoscale_on=True *and* the hline
is outside the current bounds. Something like:

        ymin, ymax = self.get_ylim()
        if ymax<ymin: ymin, ymax = ymax, ymin
        scaley = (y<ymin) or (y>ymax)

        trans = mtransforms.blended_transform_factory(
            self.transAxes, self.transData)
        l, = self.plot([xmin,xmax], [y,y], transform=trans,
scalex=False, scaley=scaley, **kwargs)

I just committed this to svn in r5141 so give it a test drive and let
me know what you think.

You are right. This patch works fine for me, thanks.

There is an unrelated problem with the autoscaler which is that in the example

plot([1,2,3])
axhline(20)

it sets ymax to 20 making the hline invisible.

But there is no problem with

  axhline(20.2)

Thats why the autoscale sets the outer ticks to the boundaries.

We should probably
force the ylimits to be strictly outside the data limits in some cases
when autoscaling.

I think this would be better then the current (undefined) behaviour (sometimes
the datalines touches the boundaries and sometimes not).

For my own stuff I have used

  gca().set_ylim(ax.dataLim.intervaly*1.2)
  
for a 'autoscale' replacement.

By,

  Friedrich

···

On Thu, May 15, 2008 at 01:56:19PM -0500, John Hunter wrote:

On Thu, May 15, 2008 at 3:41 AM, Friedrich Hagedorn <friedrich_h@...380...> wrote:
> On Thu, May 15, 2008 at 10:20:23AM +0200, Friedrich Hagedorn wrote: