|
From: Maik H. <mai...@b-...> - 2015-04-09 10:06:38
|
Hello, I'm using mpl_toolkits.axisartist.floating_axes.GridHelperCurveLinear for creating half-polar plots from 180 degree measurements for receive sensitivity. Working with the measurement values itself is no problem if I let the values scaling start at zero. If I use normalized values I can plot it also, but if I transform it into the dB scale I got a segfault in this lib. I provide an example. For my problems I would like to have a solution that I can either use r limit from -30 to 0 (f3) or changing the tick labels in figure f2. And by the way is there a possibility that the if i want to plot data in the range from 80 to 120, that rlim(80,120) would set the 80 to the centerpoint? At the moment I got only a small stripe. [code] """Demo of polar plot of arbitrary theta. This is a workaround for MPL's polar plot limitation to a full 360 deg. Based on http://matplotlib.org/mpl_toolkits/axes_grid/examples/demo_floating_axes.py get from https://github.com/neuropy/neuropy/blob/master/neuropy/scripts/polar_demo.py TODO: license / copyright """ from __future__ import division from __future__ import print_function import numpy as np import matplotlib.pyplot as plt from matplotlib.transforms import Affine2D from matplotlib.projections import PolarAxes from mpl_toolkits.axisartist import angle_helper from mpl_toolkits.axisartist.grid_finder import MaxNLocator from mpl_toolkits.axisartist.floating_axes import GridHelperCurveLinear, FloatingSubplot def fractional_polar_axes(f, thlim=(0, 180), rlim=(0, 1), step=(30, 0.2), thlabel='theta', rlabel='r', ticklabels=True, theta_offset=0): """Return polar axes that adhere to desired theta (in deg) and r limits. steps for theta and r are really just hints for the locators.""" th0, th1 = thlim # deg r0, r1 = rlim thstep, rstep = step tr_rotate = Affine2D().translate(theta_offset, 0) # scale degrees to radians: tr_scale = Affine2D().scale(np.pi/180., 1.) #pa = axes(polar="true") # Create a polar axis pa = PolarAxes tr = tr_rotate + tr_scale + pa.PolarTransform() theta_grid_locator = angle_helper.LocatorDMS((th1-th0)//thstep) r_grid_locator = MaxNLocator((r1-r0)//rstep) theta_tick_formatter = angle_helper.FormatterDMS() grid_helper = GridHelperCurveLinear(tr, extremes=(th0, th1, r0, r1), grid_locator1=theta_grid_locator, grid_locator2=r_grid_locator, tick_formatter1=theta_tick_formatter, tick_formatter2=None) a = FloatingSubplot(f, 111, grid_helper=grid_helper) f.add_subplot(a) # adjust x axis (theta): a.axis["bottom"].set_visible(False) a.axis["top"].set_axis_direction("bottom") # tick direction a.axis["top"].toggle(ticklabels=ticklabels, label=bool(thlabel)) a.axis["top"].major_ticklabels.set_axis_direction("top") a.axis["top"].label.set_axis_direction("top") # adjust y axis (r): a.axis["left"].set_axis_direction("bottom") # tick direction a.axis["right"].set_axis_direction("top") # tick direction a.axis["left"].toggle(ticklabels=ticklabels, label=bool(rlabel)) # add labels: a.axis["top"].label.set_text(thlabel) a.axis["left"].label.set_text(rlabel) # create a parasite axes whose transData is theta, r: auxa = a.get_aux_axes(tr) # make aux_ax to have a clip path as in a?: auxa.patch = a.patch # this has a side effect that the patch is drawn twice, and possibly over some other # artists. So, we decrease the zorder a bit to prevent this: a.patch.zorder = -2 # add sector lines for both dimensions: thticks = grid_helper.grid_info['lon_info'][0] rticks = grid_helper.grid_info['lat_info'][0] for th in thticks[1:-1]: # all but the first and last auxa.plot([th, th], [r0, r1], '--', c='grey', zorder=-1) for ri, r in enumerate(rticks): # plot first r line as axes border in solid black only if it isn't at r=0 if ri == 0 and r != 0: ls, lw, color = 'solid', 2, 'black' else: ls, lw, color = 'dashed', 1, 'grey' # From http://stackoverflow.com/a/19828753/2020363 auxa.add_artist(plt.Circle([0, 0], radius=r, ls=ls, lw=lw, color=color, fill=False, transform=auxa.transData._b, zorder=-1)) return auxa if __name__ == '__main__': f1 = plt.figure(facecolor='white', figsize=(16/2.54, 12/2.54), dpi=600) a1 = fractional_polar_axes(f1, thlim=(-90, 90),step=(10, 0.2),theta_offset=90) # example spiral plot: thstep = 10 th = np.arange(-90, 90+thstep, thstep) # deg rstep = 1/(len(th)-1) r = np.arange(0, 1+rstep, rstep) a1.plot(th, r, 'b') f1.show() f2 = plt.figure(facecolor='white', figsize=(16/2.54, 12/2.54), dpi=600) a2 = fractional_polar_axes(f2, thlim=(-90, 90),rlim=(0,30),step=(10, 8),theta_offset=90) # example spiral plot: r2 = 20 * np.log10(r) +30 a2.plot(th, r2, 'b') f2.show() f3 = plt.figure(facecolor='white', figsize=(16/2.54, 12/2.54), dpi=600) a3 = fractional_polar_axes(f2, thlim=(-90, 90),rlim=(-30,0), step=(10, 8),theta_offset=90) # example spiral plot: r3 = 20 * np.log10(r) a3.plot(th, r2, 'b') f2.show() [\code] -- |
|
From: Thomas C. <tca...@gm...> - 2015-04-12 01:03:04
|
Malk, This is a bit of a gap in mpl currently (but has come up a couple of times ( https://github.com/matplotlib/matplotlib/issues/4217, https://github.com/matplotlib/matplotlib/issues/2203, and http://matplotlib.org/devdocs/devel/MEP/MEP24.html). One of the hold ups has been lack of a developer that uses polar plots day-to-day and a lack of really clear use cases. I think we have three (at least) distinct use cases. 1. origin always an 0, negative radius rotates by pi, always full 2pi around, always solid circle (no inner axes) (useful for plotting bunches of vectors against each other) 2. center is at arbitrary 'r', values less than 'origin' are just not shown, always full 2pi, no inner axes (use for for dB plots showing power as function of angle) 3. inner axes with arbitrary origin, possibly not full 2pi It is not immediately clear to me if these can all be done with the same projection or even if they can be done with the 'standard' Axes class or if we need to user AxesArtist here. This discussion should probably move to MEP24/the devel list. What version of mpl are you using? Your example causes seg-faults (!) on my system, but I have not sorted out why (may be really strange install issues on my end). Tom On Thu, Apr 9, 2015 at 6:08 AM Maik Hoffmann <mai...@b-...> wrote: > Hello, > I'm using mpl_toolkits.axisartist.floating_axes.GridHelperCurveLinear > for creating half-polar plots from 180 degree measurements for receive > sensitivity. > > Working with the measurement values itself is no problem if I let the > values scaling start at zero. > If I use normalized values I can plot it also, but if I transform it > into the dB scale I got a segfault in this lib. > > I provide an example. For my problems I would like to have a solution > that I can either use r limit from -30 to 0 (f3) or changing the tick > labels in figure f2. > > And by the way is there a possibility that the if i want to plot data in > the range from 80 to 120, that rlim(80,120) would set the 80 to the > centerpoint? At the moment I got only a small stripe. > > [code] > """Demo of polar plot of arbitrary theta. This is a workaround for MPL's > polar plot limitation > to a full 360 deg. > > Based on > http://matplotlib.org/mpl_toolkits/axes_grid/examples/ > demo_floating_axes.py > > get from > https://github.com/neuropy/neuropy/blob/master/neuropy/ > scripts/polar_demo.py > TODO: license / copyright > """ > > from __future__ import division > from __future__ import print_function > > import numpy as np > import matplotlib.pyplot as plt > > from matplotlib.transforms import Affine2D > from matplotlib.projections import PolarAxes > from mpl_toolkits.axisartist import angle_helper > from mpl_toolkits.axisartist.grid_finder import MaxNLocator > from mpl_toolkits.axisartist.floating_axes import GridHelperCurveLinear, > FloatingSubplot > > > def fractional_polar_axes(f, thlim=(0, 180), rlim=(0, 1), step=(30, 0.2), > thlabel='theta', rlabel='r', ticklabels=True, > theta_offset=0): > """Return polar axes that adhere to desired theta (in deg) and r > limits. steps for theta > and r are really just hints for the locators.""" > th0, th1 = thlim # deg > r0, r1 = rlim > thstep, rstep = step > > tr_rotate = Affine2D().translate(theta_offset, 0) > # scale degrees to radians: > tr_scale = Affine2D().scale(np.pi/180., 1.) > #pa = axes(polar="true") # Create a polar axis > pa = PolarAxes > tr = tr_rotate + tr_scale + pa.PolarTransform() > theta_grid_locator = angle_helper.LocatorDMS((th1-th0)//thstep) > r_grid_locator = MaxNLocator((r1-r0)//rstep) > theta_tick_formatter = angle_helper.FormatterDMS() > > grid_helper = GridHelperCurveLinear(tr, > extremes=(th0, th1, r0, r1), > grid_locator1=theta_grid_locator, > grid_locator2=r_grid_locator, > > tick_formatter1=theta_tick_formatter, > tick_formatter2=None) > > a = FloatingSubplot(f, 111, grid_helper=grid_helper) > > f.add_subplot(a) > > # adjust x axis (theta): > a.axis["bottom"].set_visible(False) > a.axis["top"].set_axis_direction("bottom") # tick direction > a.axis["top"].toggle(ticklabels=ticklabels, label=bool(thlabel)) > a.axis["top"].major_ticklabels.set_axis_direction("top") > a.axis["top"].label.set_axis_direction("top") > > # adjust y axis (r): > a.axis["left"].set_axis_direction("bottom") # tick direction > a.axis["right"].set_axis_direction("top") # tick direction > a.axis["left"].toggle(ticklabels=ticklabels, label=bool(rlabel)) > > # add labels: > a.axis["top"].label.set_text(thlabel) > a.axis["left"].label.set_text(rlabel) > > # create a parasite axes whose transData is theta, r: > auxa = a.get_aux_axes(tr) > # make aux_ax to have a clip path as in a?: > auxa.patch = a.patch > # this has a side effect that the patch is drawn twice, and > possibly over some other > # artists. So, we decrease the zorder a bit to prevent this: > a.patch.zorder = -2 > > > # add sector lines for both dimensions: > thticks = grid_helper.grid_info['lon_info'][0] > rticks = grid_helper.grid_info['lat_info'][0] > for th in thticks[1:-1]: # all but the first and last > auxa.plot([th, th], [r0, r1], '--', c='grey', zorder=-1) > for ri, r in enumerate(rticks): > # plot first r line as axes border in solid black only if it > isn't at r=0 > if ri == 0 and r != 0: > ls, lw, color = 'solid', 2, 'black' > else: > ls, lw, color = 'dashed', 1, 'grey' > # From http://stackoverflow.com/a/19828753/2020363 > auxa.add_artist(plt.Circle([0, 0], radius=r, ls=ls, lw=lw, > color=color, fill=False, > transform=auxa.transData._b, zorder=-1)) > > return auxa > > > if __name__ == '__main__': > f1 = plt.figure(facecolor='white', figsize=(16/2.54, 12/2.54), > dpi=600) > a1 = fractional_polar_axes(f1, thlim=(-90, 90),step=(10, > 0.2),theta_offset=90) > # example spiral plot: > thstep = 10 > th = np.arange(-90, 90+thstep, thstep) # deg > rstep = 1/(len(th)-1) > r = np.arange(0, 1+rstep, rstep) > a1.plot(th, r, 'b') > > > f1.show() > > f2 = plt.figure(facecolor='white', figsize=(16/2.54, 12/2.54), > dpi=600) > a2 = fractional_polar_axes(f2, thlim=(-90, > 90),rlim=(0,30),step=(10, 8),theta_offset=90) > # example spiral plot: > r2 = 20 * np.log10(r) +30 > a2.plot(th, r2, 'b') > > f2.show() > > f3 = plt.figure(facecolor='white', figsize=(16/2.54, 12/2.54), > dpi=600) > a3 = fractional_polar_axes(f2, thlim=(-90, 90),rlim=(-30,0), > step=(10, 8),theta_offset=90) > # example spiral plot: > r3 = 20 * np.log10(r) > a3.plot(th, r2, 'b') > > f2.show() > > [\code] > > -- > > > ------------------------------------------------------------ > ------------------ > BPM Camp - Free Virtual Workshop May 6th at 10am PDT/1PM EDT > Develop your own process in accordance with the BPMN 2 standard > Learn Process modeling best practices with Bonita BPM through live > exercises > http://www.bonitasoft.com/be-part-of-it/events/bpm-camp-virtual- > event?utm_ > source=Sourceforge_BPM_Camp_5_6_15&utm_medium=email&utm_campaign=VA_SF > _______________________________________________ > Matplotlib-users mailing list > Mat...@li... > https://lists.sourceforge.net/lists/listinfo/matplotlib-users > |
|
From: Maik H. <mai...@b-...> - 2015-04-17 05:46:26
|
Hi, with normal polar plot it would work, but there is the problem with the half plot. So I use AxisArtist already. The segfault is caused by GridHelperCurveLinear and it appears on all my Computers here Python 2.7 (2 x Win7 64Bit, 1xWin7 32Bit, 2x Linux 64Bit) and mpl 1.4.2 The current solution would work for me, if I could change the axis tick labels created with axisartist. Maik Am 12.04.2015 um 03:02 schrieb Thomas Caswell: > Malk, > > This is a bit of a gap in mpl currently (but has come up a couple of times ( > https://github.com/matplotlib/matplotlib/issues/4217, > https://github.com/matplotlib/matplotlib/issues/2203, and > http://matplotlib.org/devdocs/devel/MEP/MEP24.html). > > One of the hold ups has been lack of a developer that uses polar plots > day-to-day and a lack of really clear use cases. I think we have three (at > least) distinct use cases. > > 1. origin always an 0, negative radius rotates by pi, always full 2pi > around, always solid circle (no inner axes) (useful for plotting bunches of > vectors against each other) > 2. center is at arbitrary 'r', values less than 'origin' are just not > shown, always full 2pi, no inner axes (use for for dB plots showing power > as function of angle) > 3. inner axes with arbitrary origin, possibly not full 2pi > > It is not immediately clear to me if these can all be done with the same > projection or even if they can be done with the 'standard' Axes class or if > we need to user AxesArtist here. > > This discussion should probably move to MEP24/the devel list. > > What version of mpl are you using? Your example causes seg-faults (!) on > my system, but I have not sorted out why (may be really strange install > issues on my end). > > Tom > > On Thu, Apr 9, 2015 at 6:08 AM Maik Hoffmann <mai...@b-...> wrote: > >> Hello, >> I'm using mpl_toolkits.axisartist.floating_axes.GridHelperCurveLinear >> for creating half-polar plots from 180 degree measurements for receive >> sensitivity. >> >> Working with the measurement values itself is no problem if I let the >> values scaling start at zero. >> If I use normalized values I can plot it also, but if I transform it >> into the dB scale I got a segfault in this lib. >> >> I provide an example. For my problems I would like to have a solution >> that I can either use r limit from -30 to 0 (f3) or changing the tick >> labels in figure f2. >> >> And by the way is there a possibility that the if i want to plot data in >> the range from 80 to 120, that rlim(80,120) would set the 80 to the >> centerpoint? At the moment I got only a small stripe. >> >> [code] >> """Demo of polar plot of arbitrary theta. This is a workaround for MPL's >> polar plot limitation >> to a full 360 deg. >> >> Based on >> http://matplotlib.org/mpl_toolkits/axes_grid/examples/ >> demo_floating_axes.py >> >> get from >> https://github.com/neuropy/neuropy/blob/master/neuropy/ >> scripts/polar_demo.py >> TODO: license / copyright >> """ >> >> from __future__ import division >> from __future__ import print_function >> >> import numpy as np >> import matplotlib.pyplot as plt >> >> from matplotlib.transforms import Affine2D >> from matplotlib.projections import PolarAxes >> from mpl_toolkits.axisartist import angle_helper >> from mpl_toolkits.axisartist.grid_finder import MaxNLocator >> from mpl_toolkits.axisartist.floating_axes import GridHelperCurveLinear, >> FloatingSubplot >> >> >> def fractional_polar_axes(f, thlim=(0, 180), rlim=(0, 1), step=(30, 0.2), >> thlabel='theta', rlabel='r', ticklabels=True, >> theta_offset=0): >> """Return polar axes that adhere to desired theta (in deg) and r >> limits. steps for theta >> and r are really just hints for the locators.""" >> th0, th1 = thlim # deg >> r0, r1 = rlim >> thstep, rstep = step >> >> tr_rotate = Affine2D().translate(theta_offset, 0) >> # scale degrees to radians: >> tr_scale = Affine2D().scale(np.pi/180., 1.) >> #pa = axes(polar="true") # Create a polar axis >> pa = PolarAxes >> tr = tr_rotate + tr_scale + pa.PolarTransform() >> theta_grid_locator = angle_helper.LocatorDMS((th1-th0)//thstep) >> r_grid_locator = MaxNLocator((r1-r0)//rstep) >> theta_tick_formatter = angle_helper.FormatterDMS() >> >> grid_helper = GridHelperCurveLinear(tr, >> extremes=(th0, th1, r0, r1), >> grid_locator1=theta_grid_locator, >> grid_locator2=r_grid_locator, >> >> tick_formatter1=theta_tick_formatter, >> tick_formatter2=None) >> >> a = FloatingSubplot(f, 111, grid_helper=grid_helper) >> >> f.add_subplot(a) >> >> # adjust x axis (theta): >> a.axis["bottom"].set_visible(False) >> a.axis["top"].set_axis_direction("bottom") # tick direction >> a.axis["top"].toggle(ticklabels=ticklabels, label=bool(thlabel)) >> a.axis["top"].major_ticklabels.set_axis_direction("top") >> a.axis["top"].label.set_axis_direction("top") >> >> # adjust y axis (r): >> a.axis["left"].set_axis_direction("bottom") # tick direction >> a.axis["right"].set_axis_direction("top") # tick direction >> a.axis["left"].toggle(ticklabels=ticklabels, label=bool(rlabel)) >> >> # add labels: >> a.axis["top"].label.set_text(thlabel) >> a.axis["left"].label.set_text(rlabel) >> >> # create a parasite axes whose transData is theta, r: >> auxa = a.get_aux_axes(tr) >> # make aux_ax to have a clip path as in a?: >> auxa.patch = a.patch >> # this has a side effect that the patch is drawn twice, and >> possibly over some other >> # artists. So, we decrease the zorder a bit to prevent this: >> a.patch.zorder = -2 >> >> >> # add sector lines for both dimensions: >> thticks = grid_helper.grid_info['lon_info'][0] >> rticks = grid_helper.grid_info['lat_info'][0] >> for th in thticks[1:-1]: # all but the first and last >> auxa.plot([th, th], [r0, r1], '--', c='grey', zorder=-1) >> for ri, r in enumerate(rticks): >> # plot first r line as axes border in solid black only if it >> isn't at r=0 >> if ri == 0 and r != 0: >> ls, lw, color = 'solid', 2, 'black' >> else: >> ls, lw, color = 'dashed', 1, 'grey' >> # From http://stackoverflow.com/a/19828753/2020363 >> auxa.add_artist(plt.Circle([0, 0], radius=r, ls=ls, lw=lw, >> color=color, fill=False, >> transform=auxa.transData._b, zorder=-1)) >> >> return auxa >> >> >> if __name__ == '__main__': >> f1 = plt.figure(facecolor='white', figsize=(16/2.54, 12/2.54), >> dpi=600) >> a1 = fractional_polar_axes(f1, thlim=(-90, 90),step=(10, >> 0.2),theta_offset=90) >> # example spiral plot: >> thstep = 10 >> th = np.arange(-90, 90+thstep, thstep) # deg >> rstep = 1/(len(th)-1) >> r = np.arange(0, 1+rstep, rstep) >> a1.plot(th, r, 'b') >> >> >> f1.show() >> >> f2 = plt.figure(facecolor='white', figsize=(16/2.54, 12/2.54), >> dpi=600) >> a2 = fractional_polar_axes(f2, thlim=(-90, >> 90),rlim=(0,30),step=(10, 8),theta_offset=90) >> # example spiral plot: >> r2 = 20 * np.log10(r) +30 >> a2.plot(th, r2, 'b') >> >> f2.show() >> >> f3 = plt.figure(facecolor='white', figsize=(16/2.54, 12/2.54), >> dpi=600) >> a3 = fractional_polar_axes(f2, thlim=(-90, 90),rlim=(-30,0), >> step=(10, 8),theta_offset=90) >> # example spiral plot: >> r3 = 20 * np.log10(r) >> a3.plot(th, r2, 'b') >> >> f2.show() >> >> [\code] >> >> -- >> >> >> ------------------------------------------------------------ >> ------------------ >> BPM Camp - Free Virtual Workshop May 6th at 10am PDT/1PM EDT >> Develop your own process in accordance with the BPMN 2 standard >> Learn Process modeling best practices with Bonita BPM through live >> exercises >> http://www.bonitasoft.com/be-part-of-it/events/bpm-camp-virtual- >> event?utm_ >> source=Sourceforge_BPM_Camp_5_6_15&utm_medium=email&utm_campaign=VA_SF >> _______________________________________________ >> Matplotlib-users mailing list >> Mat...@li... >> https://lists.sourceforge.net/lists/listinfo/matplotlib-users >> > -- wissenschaftlicher Mitarbeiter Lehrstuhl Allgemeine Elektrotechnik und Messtechnik (AEMT) Fakultät Maschinenbau, Elektrotechnik und Wirtschaftsingenieurwesen Brandenburgische Technische Universität Cottbus Siemens-Halske-Ring 14 D-03046 Cottbus Tel.: +49-355-69-3425 Fax: +49-355-69-4104 http://www.tu-cottbus.de/fakultaet3/de/elektrotechnik-messtechnik/ |