Discussion:
[Matplotlib-users] segfault creating polarplot with GridHelperCurveLinear
Maik Hoffmann
2015-04-09 09:41:46 UTC
Permalink
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]

--
Thomas Caswell
2015-04-12 01:02:55 UTC
Permalink
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
Post by Maik Hoffmann
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,
"""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)
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)
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")
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))
a.axis["top"].label.set_text(thlabel)
a.axis["left"].label.set_text(rlabel)
auxa = a.get_aux_axes(tr)
auxa.patch = a.patch
# this has a side effect that the patch is drawn twice, and
possibly over some other
a.patch.zorder = -2
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)
# plot first r line as axes border in solid black only if it
isn't at r=0
ls, lw, color = 'solid', 2, 'black'
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
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)
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)
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)
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
https://lists.sourceforge.net/lists/listinfo/matplotlib-users
Maik Hoffmann
2015-04-17 05:46:08 UTC
Permalink
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
Post by 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
Post by Maik Hoffmann
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,
"""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)
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)
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")
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))
a.axis["top"].label.set_text(thlabel)
a.axis["left"].label.set_text(rlabel)
auxa = a.get_aux_axes(tr)
auxa.patch = a.patch
# this has a side effect that the patch is drawn twice, and
possibly over some other
a.patch.zorder = -2
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)
# plot first r line as axes border in solid black only if it
isn't at r=0
ls, lw, color = 'solid', 2, 'black'
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
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)
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)
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)
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
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/
Loading...