|
From: Ilya S. <ily...@al...> - 2011-01-23 00:06:10
|
Is it possible to create a "break" in the y-axis so that it has ticks for value 0-.2, then ticks for values .8-1.0, but devotes only a token amount of space to the area 0.2-0.8? I have a dataset with most datapoints in 0-.2 and a couple in .8-1.0, and none in .2-.8 . The default scaling wastes a lot of space and compresses the data in the 0-.2 range such that it is hard to distinguish. Thanks for any help! Ilya p.s. I know I could use two y-axes with different scales; but this would require splitting the data into two different datasets as well, and would not allow connecting all points with one line. |
|
From: Paul I. <piv...@gm...> - 2011-01-23 02:28:37
|
Ilya Shlyakhter, on 2011-01-22 19:06, wrote: > Is it possible to create a "break" in the y-axis so that it has ticks > for value 0-.2, then ticks for values .8-1.0, but devotes only a token > amount of space to the area 0.2-0.8? > I have a dataset with most datapoints in 0-.2 and a couple in .8-1.0, > and none in .2-.8 . The default scaling wastes a lot of space and > compresses the data in the 0-.2 range > such that it is hard to distinguish. Hi Ilya, this... > p.s. I know I could use two y-axes with different scales; but this > would require splitting the data into two different datasets as well, > and would not allow connecting all points > with one line. ... is the way I'd proceed, because it's clean, and requires the least amount of work. Connecting your lines across such breaks is misleading - since the magnitude of the slope of the connecting line segment arbitrary relative to all other line segments. You don't actually have to divide your data, you can just replot *all* data on the secondary plot, and then set the x and y lims to break up your views on the data. I'm attaching a quick sketch of what that would look like. (Note how different the outlier line segments would look if we connected them in the same manner that all other points are connected). import numpy as np import matplotlib.pylab as plt pts = np.random.rand(30)*.2 pts[[7,11]] += .8 f,(ax,ax2) = plt.subplots(2,1,sharex=True) ax.plot(pts) ax2.plot(pts) ax.set_ylim(.78,1.) ax2.set_ylim(0,.22) ax.xaxis.tick_top() ax.spines['bottom'].set_visible(False) ax.tick_params(labeltop='off') ax2.xaxis.tick_bottom() ax2.spines['top'].set_visible(False) If this is something you really want, though, you can achieve it by making your own projection/scale: http://matplotlib.sourceforge.net/devel/add_new_projection.html Yet another way would be to re-label the tick lines (e.g. make .6 label be 1.0 and subtract that offset from your two outliers. best, -- Paul Ivanov 314 address only used for lists, off-list direct email at: http://pirsquared.org | GPG/PGP key id: 0x0F3E28F7 |
|
From: Paul I. <piv...@gm...> - 2011-01-23 03:16:28
Attachments:
snipped_ticks.png
|
Paul Ivanov, on 2011-01-22 18:28, wrote: > Ilya Shlyakhter, on 2011-01-22 19:06, wrote: > > Is it possible to create a "break" in the y-axis so that it has ticks > > for value 0-.2, then ticks for values .8-1.0, but devotes only a token > > amount of space to the area 0.2-0.8? > > I have a dataset with most datapoints in 0-.2 and a couple in .8-1.0, > > and none in .2-.8 . The default scaling wastes a lot of space and > > compresses the data in the 0-.2 range > > such that it is hard to distinguish. > > Hi Ilya, > > this... > > > p.s. I know I could use two y-axes with different scales; but this > > would require splitting the data into two different datasets as well, > > and would not allow connecting all points > > with one line. > > ... is the way I'd proceed, because it's clean, and requires the > least amount of work. Connecting your lines across such breaks > is misleading - since the magnitude of the slope of the > connecting line segment arbitrary relative to all other line > segments. You don't actually have to divide your data, you can > just replot *all* data on the secondary plot, and then set the x > and y lims to break up your views on the data. I'm attaching a > quick sketch of what that would look like. (Note how different > the outlier line segments would look if we connected them in the > same manner that all other points are connected). > > import numpy as np > import matplotlib.pylab as plt > pts = np.random.rand(30)*.2 > pts[[7,11]] += .8 > f,(ax,ax2) = plt.subplots(2,1,sharex=True) > > ax.plot(pts) > ax2.plot(pts) > ax.set_ylim(.78,1.) > ax2.set_ylim(0,.22) > > ax.xaxis.tick_top() > ax.spines['bottom'].set_visible(False) > ax.tick_params(labeltop='off') > ax2.xaxis.tick_bottom() > ax2.spines['top'].set_visible(False) > > If this is something you really want, though, you can achieve it > by making your own projection/scale: > http://matplotlib.sourceforge.net/devel/add_new_projection.html > > Yet another way would be to re-label the tick lines (e.g. make .6 > label be 1.0 and subtract that offset from your two outliers. forgot the attachment, here it is. -- Paul Ivanov 314 address only used for lists, off-list direct email at: http://pirsquared.org | GPG/PGP key id: 0x0F3E28F7 |
|
From: Eric F. <ef...@ha...> - 2011-01-23 03:49:41
|
On 01/22/2011 05:16 PM, Paul Ivanov wrote: > Paul Ivanov, on 2011-01-22 18:28, wrote: >> Ilya Shlyakhter, on 2011-01-22 19:06, wrote: >>> Is it possible to create a "break" in the y-axis so that it has ticks >>> for value 0-.2, then ticks for values .8-1.0, but devotes only a token >>> amount of space to the area 0.2-0.8? >>> I have a dataset with most datapoints in 0-.2 and a couple in .8-1.0, >>> and none in .2-.8 . The default scaling wastes a lot of space and >>> compresses the data in the 0-.2 range >>> such that it is hard to distinguish. >> >> Hi Ilya, >> >> this... Paul, Your example below is nice, and this question comes up quite often. If we don't already have a gallery example of this, you might want to add one. (Probably better to use deterministic fake data rather than random.) Eric >> >>> p.s. I know I could use two y-axes with different scales; but this >>> would require splitting the data into two different datasets as well, >>> and would not allow connecting all points >>> with one line. >> >> ... is the way I'd proceed, because it's clean, and requires the >> least amount of work. Connecting your lines across such breaks >> is misleading - since the magnitude of the slope of the >> connecting line segment arbitrary relative to all other line >> segments. You don't actually have to divide your data, you can >> just replot *all* data on the secondary plot, and then set the x >> and y lims to break up your views on the data. I'm attaching a >> quick sketch of what that would look like. (Note how different >> the outlier line segments would look if we connected them in the >> same manner that all other points are connected). >> >> import numpy as np >> import matplotlib.pylab as plt >> pts = np.random.rand(30)*.2 >> pts[[7,11]] += .8 >> f,(ax,ax2) = plt.subplots(2,1,sharex=True) >> >> ax.plot(pts) >> ax2.plot(pts) >> ax.set_ylim(.78,1.) >> ax2.set_ylim(0,.22) >> >> ax.xaxis.tick_top() >> ax.spines['bottom'].set_visible(False) >> ax.tick_params(labeltop='off') >> ax2.xaxis.tick_bottom() >> ax2.spines['top'].set_visible(False) >> >> If this is something you really want, though, you can achieve it >> by making your own projection/scale: >> http://matplotlib.sourceforge.net/devel/add_new_projection.html >> >> Yet another way would be to re-label the tick lines (e.g. make .6 >> label be 1.0 and subtract that offset from your two outliers. > > forgot the attachment, here it is. > > > > > ------------------------------------------------------------------------------ > Special Offer-- Download ArcSight Logger for FREE (a $49 USD value)! > Finally, a world-class log management solution at an even better price-free! > Download using promo code Free_Logger_4_Dev2Dev. Offer expires > February 28th, so secure your free ArcSight Logger TODAY! > http://p.sf.net/sfu/arcsight-sfd2d > > > > _______________________________________________ > Matplotlib-users mailing list > Mat...@li... > https://lists.sourceforge.net/lists/listinfo/matplotlib-users |
|
From: Paul I. <piv...@gm...> - 2011-01-24 09:47:05
Attachments:
broken_axis.png
|
Eric Firing, on 2011-01-22 17:49, wrote: > >> Paul Ivanov, on 2011-01-22 18:28, wrote: > > Paul, > > Your example below is nice, and this question comes up quite often. If > we don't already have a gallery example of this, you might want to add > one. (Probably better to use deterministic fake data rather than random.) > > >> > >> import numpy as np > >> import matplotlib.pylab as plt > >> pts = np.random.rand(30)*.2 > >> pts[[7,11]] += .8 > >> f,(ax,ax2) = plt.subplots(2,1,sharex=True) > >> > >> ax.plot(pts) > >> ax2.plot(pts) > >> ax.set_ylim(.78,1.) > >> ax2.set_ylim(0,.22) > >> > >> ax.xaxis.tick_top() > >> ax.spines['bottom'].set_visible(False) > >> ax.tick_params(labeltop='off') > >> ax2.xaxis.tick_bottom() > >> ax2.spines['top'].set_visible(False) Done in r8935, see examples/pylab_examples/broken_axis.py I documented the above, used deterministic fake data, as Eric suggested, and added the diagonal cut lines that usually accompany a broken axis. Here's the tail end of the script which creates that effect (see updated attached image). # This looks pretty good, and was fairly painless, but you can # get that cut-out diagonal lines look with just a bit more # work. The important thing to know here is that in axes # coordinates, which are always between 0-1, spine endpoints # are at these locations (0,0), (0,1), (1,0), and (1,1). Thus, # we just need to put the diagonals in the appropriate corners # of each of our axes, and so long as we use the right # transform and disable clipping. d = .015 # how big to make the diagonal lines in axes coordinates # arguments to pass plot, just so we don't keep repeating them kwargs = dict(transform=ax.transAxes, color='k', clip_on=False) ax.plot((-d,+d),(-d,+d), **kwargs) # top-left diagonal ax.plot((1-d,1+d),(-d,+d), **kwargs) # top-right diagonal kwargs.update(transform=ax2.transAxes) # switch to the bottom axes ax2.plot((-d,+d),(1-d,1+d), **kwargs) # bottom-left diagonal ax2.plot((1-d,1+d),(1-d,1+d), **kwargs) # bottom-right diagonal # What's cool about this is that now if we vary the distance # between ax and ax2 via f.subplots_adjust(hspace=...) or # plt.subplot_tool(), the diagonal lines will move accordingly, # and stay right at the tips of the spines they are 'breaking' best, -- Paul Ivanov 314 address only used for lists, off-list direct email at: http://pirsquared.org | GPG/PGP key id: 0x0F3E28F7 |
|
From: Eric F. <ef...@ha...> - 2011-01-24 18:25:12
|
On 01/23/2011 11:46 PM, Paul Ivanov wrote: [...] > Done in r8935, see examples/pylab_examples/broken_axis.py > Thank you. > I documented the above, used deterministic fake data, as Eric > suggested, and added the diagonal cut lines that usually > accompany a broken axis. Here's the tail end of the script which > creates that effect (see updated attached image). Beautiful! Eric > > # This looks pretty good, and was fairly painless, but you can > # get that cut-out diagonal lines look with just a bit more > # work. The important thing to know here is that in axes > # coordinates, which are always between 0-1, spine endpoints > # are at these locations (0,0), (0,1), (1,0), and (1,1). Thus, > # we just need to put the diagonals in the appropriate corners > # of each of our axes, and so long as we use the right > # transform and disable clipping. > > d = .015 # how big to make the diagonal lines in axes coordinates > # arguments to pass plot, just so we don't keep repeating them > kwargs = dict(transform=ax.transAxes, color='k', clip_on=False) > ax.plot((-d,+d),(-d,+d), **kwargs) # top-left diagonal > ax.plot((1-d,1+d),(-d,+d), **kwargs) # top-right diagonal > > kwargs.update(transform=ax2.transAxes) # switch to the bottom axes > ax2.plot((-d,+d),(1-d,1+d), **kwargs) # bottom-left diagonal > ax2.plot((1-d,1+d),(1-d,1+d), **kwargs) # bottom-right diagonal > > # What's cool about this is that now if we vary the distance > # between ax and ax2 via f.subplots_adjust(hspace=...) or > # plt.subplot_tool(), the diagonal lines will move accordingly, > # and stay right at the tips of the spines they are 'breaking' > > best, |