Re: [Matplotlib-users] Bug in boxplot/mlab.prctile
2011/1/1 OKB (not okblacke) brenb...@brenbarn.net: I noticed that the boxplot function incorrectly calculates the location of the median line in each box. As a simple example, plotting the dataset [1, 2, 3, 4] incorrectly plots the median line at 3. It seems to work fine in matplotlib 1.0.0: u...@host:~$ python Python 2.6.6 (r266:84292, Sep 15 2010, 16:22:56) [GCC 4.4.5] on linux2 Type help, copyright, credits or license for more information. import matplotlib as mpl mpl.__version__ '1.0.0' import matplotlib.pyplot as plt import matplotlib.mlab as mlab plt.ion() plt.boxplot([1, 2, 3, 4]) {'medians': [matplotlib.lines.Line2D object at 0x3ad6250], 'fliers': [matplotlib.lines.Line2D object at 0x3ad6610, matplotlib.lines.Line2D object at 0x3ad69d0], 'whiskers': [matplotlib.lines.Line2D object at 0x3acff50, matplotlib.lines.Line2D object at 0x3ad4310], 'boxes': [matplotlib.lines.Line2D object at 0x3ad4e50], 'caps': [matplotlib.lines.Line2D object at 0x3ad46d0, matplotlib.lines.Line2D object at 0x3ad4a90]} plt.grid() plt.boxplot([1, 2, 3, 4]) {'medians': [matplotlib.lines.Line2D object at 0x3dfbad0], 'fliers': [matplotlib.lines.Line2D object at 0x3dfbe90, matplotlib.lines.Line2D object at 0x3dff290], 'whiskers': [matplotlib.lines.Line2D object at 0x3df8810, matplotlib.lines.Line2D object at 0x3df8b90], 'boxes': [matplotlib.lines.Line2D object at 0x3dfb710], 'caps': [matplotlib.lines.Line2D object at 0x3df8f50, matplotlib.lines.Line2D object at 0x3dfb350]} plt.grid() # See attached image. ... mlab.prctile([1, 2, 3, 4]) array([ 1. , 1.75, 2.5 , 3.25, 4. ]) Goyo It also seems that the quartile calculations for the box are a little peculiar. I have seen some discussion in old mailing list postings about mlab.prctile and its ways of calculating percentiles, which are different than those of some other software. I'm aware that there is legitimate disagreement about the best way to calculate the quartiles. However, it seems to me that mlab's way is still not any of these possibly-correct ways, because it uses int() or nparray.astype(int) to coerce the percentile result to an integer index. This TRUNCATES the floating-point result. No accepted quantile- calculating method that I'm aware of does this; they all ROUND instead of truncating (if they want to coerce to an integer index at all, in order to produce a quantile value that is an element of the data set), or in some cases they round uniformly up for the lower quartile and down for the upper. You can see a summary of different methods at http://www.amstat.org/publications/jse/v14n3/langford.html ; the method used by mlab does not appear to agree with any of these. I would suggest that mlab.prctile be fixed to conform to some one or other of these methods, rather than adding to the proliferation of approaches to quantile-calculation. Is there any motivation for always truncating to integer (other that it's quicker to type :-)? Also, regardless of these quartile issues, there is, as far as I'm aware, no one who denies that the median of a (sorted) data set with an even number of values is the mean of the middle two values. Since numpy is already a dependency for matplotlib, boxplot shouldn't use mlab.prctile at all to decide where to plot the median line -- just use numpy.median. Thanks, -- --OKB (not okblacke) Brendan Barnwell Do not follow where the path may lead. Go, instead, where there is no path, and leave a trail. --author unknown attachment: boxplot_sample.png-- Learn how Oracle Real Application Clusters (RAC) One Node allows customers to consolidate database storage, standardize their database environment, and, should the need arise, upgrade to a full multi-node Oracle RAC database without downtime or disruption http://p.sf.net/sfu/oracle-sfdevnl___ Matplotlib-users mailing list Matplotlib-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/matplotlib-users
[Matplotlib-users] whitespace around custom projection
Hi all, I've created a custom projection for drawing Lambert plots on two adjacent hemispheres, copied closely from the custom_projection_example [1], and attached here. The basics are working I think, but the axes objects have too much whitespace around them, and I can't immediately work out what approach to take to reduce it to something reasonable. Can anyone point me in the right direction? Ultimately I'm hoping to be able to put several of these plots together in a figure, which is currently not practical. (Also, pcolor doesn't work as I expect, but I need to play around with that a bit more before I know what question I need to ask of the list.) Thanks, Angus. [1] http://matplotlib.sourceforge.net/examples/api/custom_projection_example.html -- AJC McMorland Post-doctoral research fellow Neurobiology, University of Pittsburgh from matplotlib.axes import Axes from matplotlib import cbook, docstring from matplotlib.patches import Patch, cbook, transforms, artist from matplotlib.path import Path from matplotlib.ticker import Formatter, Locator, NullLocator, \ FixedLocator, NullFormatter from matplotlib.transforms import Affine2D, Affine2DBase, Bbox, \ BboxTransformTo, IdentityTransform, Transform, TransformWrapper from matplotlib.projections import register_projection, PolarAxes from matplotlib.projections.geo import GeoAxes, LambertAxes import matplotlib.spines as mspines import matplotlib.axis as maxis from copy import copy from split_lambert_transforms import SplitLambertTransform import numpy as np class TwoCircle(Patch): A scale-free ellipse. def __str__(self): return TwoCircle(%s, %s; %s) % (self.center[0], self.center[1], self.radius) @docstring.dedent_interpd def __init__(self, xy, radius, **kwargs): xy : array_like center of two circles radius : scalar size of each circle Valid kwargs are: %(Patch)s Patch.__init__(self, **kwargs) self.center = xy self.radius = radius self.width = 2 * radius self.height = 2. * radius path = copy(Path.unit_circle()) n_pts = path.vertices.shape[0] path.vertices = np.tile(path.vertices, [2,1]) path.vertices[:n_pts,0] -= 1 path.vertices[n_pts:,0] += 1 path.codes = np.tile(path.codes, [2]) self._path = path # Note: This cannot be calculated until this is added to an Axes self._patch_transform = transforms.IdentityTransform() def _recompute_transform(self): NOTE: This cannot be called until after this has been added to an Axes, otherwise unit conversion will fail. This makes it very important to call the accessor method and not directly access the transformation member variable. center = (self.convert_xunits(self.center[0]), self.convert_yunits(self.center[1])) width = self.convert_xunits(self.width) height = self.convert_yunits(self.height) self._patch_transform = transforms.Affine2D() \ .scale(width * 0.5, height * 0.5) \ .translate(*center) def get_path(self): Return the vertices of the rectangle return self._path def get_patch_transform(self): self._recompute_transform() return self._patch_transform def contains(self,ev): if ev.x is None or ev.y is None: return False,{} x, y = self.get_transform().inverted().transform_point((ev.x, ev.y)) r = self.radius return (((x - r) * (x - r) + y * y) = r*r) or \ (((x + r) * (x + r) + y * y) = r*r), {} class SplitLambertAxes(Axes): A custom class for the split Lambert projection, an equal-area map projection using one circle for each hemisphere. name = 'split_lambert' resolution = 75 def __init__(self, *args, **kwargs): Axes.__init__(self, *args, **kwargs) self.set_aspect(1., adjustable='box', anchor='C') self.cla() def _init_axis(self): self.xaxis = maxis.XAxis(self) # xaxis == theta == latitude self.yaxis = maxis.YAxis(self) # yaxis == phi == longitude # Do not register xaxis or yaxis with spines -- as done in # Axes._init_axis() -- until SplitLambertAxes.xaxis.cla() works. # self.spines['split_lambert'].register_axis(self.yaxis) self._update_transScale() def cla(self): Override to set up some reasonable defaults. # Don't forget to call the base class Axes.cla(self) # Set up a default grid spacing self.set_theta_grid(np.pi/4.) self.set_phi_grid(np.pi/2.) self.set_phi_grid_ends(np.pi/8.) # Turn off minor ticking altogether self.xaxis.set_minor_locator(NullLocator())
Re: [Matplotlib-users] How to make a grid of (plot) grids?
Gf B, on 2011-01-04 12:31, wrote: On Mon, Jan 3, 2011 at 3:53 PM, Paul Ivanov pivanov...@gmail.com wrote: Gf B, on 2011-01-03 15:23, wrote: Can such a grid of grids be done with matplotlib? If so, could someone show me how? You'll be able to group the inner grids visually by adjusting the spacing. As far as getting the spines to only outline the outer grid, and not the inner grid - I think you'll have to do it manually by hiding the appropriate spines for the inner subplots. This sort of ad-hoc manual tweaking is what I was hoping to avoid. What would it take to implement a true grid-of-grids function in matplotlib? What I mean by this is a function that can arrange in a grid not only plots but also other grids. (Is this a question for the devel group?) I think the true grid-of-grids functunality is already implemented. Here's a replication of your Mathematica plots: import numpy as np import matplotlib.pyplot as plt import matplotlib.gridspec as gridspec from itertools import product def squiggle_xy(a, b, c, d, i=np.linspace(0.0, 2*np.pi, 200)): return np.sin(i*a)*np.cos(i*b), np.sin(i*c)*np.cos(i*d) f = plt.figure(figsize=(8, 8)) # gridspec inside gridspec outer_grid = gridspec.GridSpec(4, 4, wspace=0.0, hspace=0.0) for i in xrange(16): inner_grid = gridspec.GridSpecFromSubplotSpec(3, 3, subplot_spec=outer_grid[i], wspace=0.0, hspace=0.0) a, b = int(i/4)+1,i%4+1 for j, (c, d) in enumerate(product(range(1, 4), repeat=2)): ax = plt.Subplot(f, inner_grid[j]) ax.plot(*squiggle_xy(a, b, c, d)) ax.set_xticks([]) ax.set_yticks([]) f.add_subplot(ax) all_axes = f.get_axes() #show only the outside spines for ax in all_axes: for sp in ax.spines.values(): sp.set_visible(False) if ax.is_first_row(): ax.spines['top'].set_visible(True) if ax.is_last_row(): ax.spines['bottom'].set_visible(True) if ax.is_first_col(): ax.spines['left'].set_visible(True) if ax.is_last_col(): ax.spines['right'].set_visible(True) plt.show() It's a matter of taste, but I think you can get away hiding all spines, and just setting the hspace and wspace for the outer_grid to some small value (this is what I meant by 'adjusting the spacing'). I'll send a patch to the devel list shortly adding this example with the following documentation A Complex Nested GridSpec using SubplotSpec === Here's a more sophisticated example of nested gridspect where we put a box around outer 4x4 grid, by hiding appropriate spines in each of the inner 3x3 grids. it'll be placed on the gridspec page, after this section: http://matplotlib.sourceforge.net/users/gridspec.html#gridspec-using-subplotspec best, -- Paul Ivanov 314 address only used for lists, off-list direct email at: http://pirsquared.org | GPG/PGP key id: 0x0F3E28F7 signature.asc Description: Digital signature -- Learn how Oracle Real Application Clusters (RAC) One Node allows customers to consolidate database storage, standardize their database environment, and, should the need arise, upgrade to a full multi-node Oracle RAC database without downtime or disruption http://p.sf.net/sfu/oracle-sfdevnl___ Matplotlib-users mailing list Matplotlib-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/matplotlib-users
Re: [Matplotlib-users] How to make a grid of (plot) grids?
On Tue, Jan 4, 2011 at 6:17 PM, Paul Ivanov pivanov...@gmail.com wrote: Gf B, on 2011-01-04 12:31, wrote: On Mon, Jan 3, 2011 at 3:53 PM, Paul Ivanov pivanov...@gmail.com wrote: Gf B, on 2011-01-03 15:23, wrote: Can such a grid of grids be done with matplotlib? If so, could someone show me how? You'll be able to group the inner grids visually by adjusting the spacing. As far as getting the spines to only outline the outer grid, and not the inner grid - I think you'll have to do it manually by hiding the appropriate spines for the inner subplots. This sort of ad-hoc manual tweaking is what I was hoping to avoid. What would it take to implement a true grid-of-grids function in matplotlib? What I mean by this is a function that can arrange in a grid not only plots but also other grids. (Is this a question for the devel group?) I think the true grid-of-grids functunality is already implemented. Here's a replication of your Mathematica plots: import numpy as np import matplotlib.pyplot as plt import matplotlib.gridspec as gridspec from itertools import product def squiggle_xy(a, b, c, d, i=np.linspace(0.0, 2*np.pi, 200)): return np.sin(i*a)*np.cos(i*b), np.sin(i*c)*np.cos(i*d) f = plt.figure(figsize=(8, 8)) # gridspec inside gridspec outer_grid = gridspec.GridSpec(4, 4, wspace=0.0, hspace=0.0) for i in xrange(16): inner_grid = gridspec.GridSpecFromSubplotSpec(3, 3, subplot_spec=outer_grid[i], wspace=0.0, hspace=0.0) a, b = int(i/4)+1,i%4+1 for j, (c, d) in enumerate(product(range(1, 4), repeat=2)): ax = plt.Subplot(f, inner_grid[j]) ax.plot(*squiggle_xy(a, b, c, d)) ax.set_xticks([]) ax.set_yticks([]) f.add_subplot(ax) all_axes = f.get_axes() #show only the outside spines for ax in all_axes: for sp in ax.spines.values(): sp.set_visible(False) if ax.is_first_row(): ax.spines['top'].set_visible(True) if ax.is_last_row(): ax.spines['bottom'].set_visible(True) if ax.is_first_col(): ax.spines['left'].set_visible(True) if ax.is_last_col(): ax.spines['right'].set_visible(True) plt.show() It's a matter of taste, but I think you can get away hiding all spines, and just setting the hspace and wspace for the outer_grid to some small value (this is what I meant by 'adjusting the spacing'). I'll send a patch to the devel list shortly adding this example with the following documentation A Complex Nested GridSpec using SubplotSpec === Here's a more sophisticated example of nested gridspect where we put a box around outer 4x4 grid, by hiding appropriate spines in each of the inner 3x3 grids. it'll be placed on the gridspec page, after this section: http://matplotlib.sourceforge.net/users/gridspec.html#gridspec-using-subplotspec best, -- Paul Ivanov 314 address only used for lists, off-list direct email at: http://pirsquared.org | GPG/PGP key id: 0x0F3E28F7 Just to add, because it is related, another tool that gives you advanced control over your axes is the AxesGrid toolkit: http://matplotlib.sourceforge.net/mpl_toolkits/axes_grid/index.html#toolkit-axesgrid-index However, gridspec should be exactly what you need for this particular problem. Ben Root -- Learn how Oracle Real Application Clusters (RAC) One Node allows customers to consolidate database storage, standardize their database environment, and, should the need arise, upgrade to a full multi-node Oracle RAC database without downtime or disruption http://p.sf.net/sfu/oracle-sfdevnl___ Matplotlib-users mailing list Matplotlib-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/matplotlib-users