I am trying to create a scatter plot with the color for each point based on the value in y-dimension and the tooltip for each point based on the value of x-axis. I was in need of creating tooltips for each point on mouseover event, which I was able to achieve. I would like to save this plot to a svg file with events so that the svg file can be viewed in a browser with tooltip.
I get the following error when I try to save it,
Traceback (most recent call last):
File "./altered_tooltip.py", line 160, in <module>
example.plot()
File "./altered_tooltip.py", line 70, in plot
pl.savefig(f, format="svg")
File "/usr/lib/pymodules/python2.7/matplotlib/pyplot.py", line 561, in savefig
return fig.savefig(*args, **kwargs)
File "/usr/lib/pymodules/python2.7/matplotlib/figure.py", line 1421, in savefig
self.canvas.print_figure(*args, **kwargs)
File "/usr/lib/pymodules/python2.7/matplotlib/backend_bases.py", line 2220, in print_figure
**kwargs)
File "/usr/lib/pymodules/python2.7/matplotlib/backend_bases.py", line 1978, in print_svg
return svg.print_svg(*args, **kwargs)
File "/usr/lib/pymodules/python2.7/matplotlib/backends/backend_svg.py", line 1157, in print_svg
return self._print_svg(filename, svgwriter, fh_to_close, **kwargs)
File "/usr/lib/pymodules/python2.7/matplotlib/backends/backend_svg.py", line 1185, in _print_svg
self.figure.draw(renderer)
File "/usr/lib/pymodules/python2.7/matplotlib/artist.py", line 55, in draw_wrapper
draw(artist, renderer, *args, **kwargs)
File "/usr/lib/pymodules/python2.7/matplotlib/figure.py", line 1034, in draw
func(*args)
File "/usr/lib/pymodules/python2.7/matplotlib/artist.py", line 55, in draw_wrapper
draw(artist, renderer, *args, **kwargs)
File "/usr/lib/pymodules/python2.7/matplotlib/axes.py", line 2086, in draw
a.draw(renderer)
File "/usr/lib/pymodules/python2.7/matplotlib/artist.py", line 55, in draw_wrapper
draw(artist, renderer, *args, **kwargs)
File "/usr/lib/pymodules/python2.7/matplotlib/collections.py", line 718, in draw
return Collection.draw(self, renderer)
File "/usr/lib/pymodules/python2.7/matplotlib/artist.py", line 55, in draw_wrapper
draw(artist, renderer, *args, **kwargs)
File "/usr/lib/pymodules/python2.7/matplotlib/collections.py", line 250, in draw
renderer.open_group(self.__class__.__name__, self.get_gid())
File "/usr/lib/pymodules/python2.7/matplotlib/backends/backend_svg.py", line 516, in open_group
self.writer.start('g', id=gid)
File "/usr/lib/pymodules/python2.7/matplotlib/backends/backend_svg.py", line 141, in start
v = escape_attrib(v)
File "/usr/lib/pymodules/python2.7/matplotlib/backends/backend_svg.py", line 80, in escape_attrib
s = s.replace(u"&", u"&")
AttributeError: 'list' object has no attribute 'replace'
The code that I am running is
from numpy import *
import pylab as pl
import matplotlib.colors as mcolors
import xml.etree.ElementTree as ET
from StringIO import StringIO
ET.register_namespace("","http://www.w3.org/2000/svg")
class wxToolTipExample(object):
def __init__(self, plot_data):
self.figure = pl.figure()
self.axis = pl.axes()
self.ax = self.figure.add_subplot(111)
self.tooltip.SetTip() calls
self.dataX = plot_data[:,0]
self.dataY = plot_data[:,1]
self.annotes = []
self.pathCol = None #to hold the scatter object
def plot(self):
for idx in arange(self.dataX.size):
# create a tuple of co-ordinates
tup = (self.dataX[idx], self.dataY[idx])
# create annotation with tooltip
annotation = self.axis.annotate("Column %s" % int(self.dataX[idx]),
xy=tup, xycoords='data',
xytext=(+10, +30), textcoords='offset points',
#horizontalalignment="right",
arrowprops=dict(arrowstyle="->",
connectionstyle="arc3,rad=0.2"),
#bbox=dict(boxstyle="round", facecolor="w",
# edgecolor="0.0", alpha=0.0)
)
# by default, disable the annotation visibility
annotation.set_visible(False)
# append the annotation object and co-ords tuple to the list
self.annotes.append([tup, annotation])
self.figure.canvas.mpl_connect('motion_notify_event', self._onMotion)
c_map = self.WGrYR()
self.pathCol = self.axis.scatter(self.dataX, self.dataY, c=self.dataY, marker='s', s=40, cmap=c_map)
# Set id for the annotations
for i, t in enumerate(self.axis.texts):
t.set_gid('tooltip_%d'%i)
# Set id for the points on the scatter plot
points = ['point_{0}'.format(ii) for ii in arange(1, self.dataX.size+1)]
self.pathCol.set_gid(points)
f = StringIO()
#pl.show()
pl.savefig(f, format="svg")
"""
# Create XML tree from the SVG file.
tree, xmlid = ET.XMLID(f.getvalue())
tree.set('onload', 'init(evt)')
# Hide the tooltips
for i, t in enumerate(self.axis.texts):
ele = xmlid['tooltip_%d'%i]
ele.set('visibility','hidden')
# assign mouseover and mouseout events
for p in points:
ele = xmlid[p]
ele.set('onmouseover', "ShowTooltip(this)")
ele.set('onmouseout', "HideTooltip(this)")
script = self.getSvgScript()
# Insert the script at the top of the file and save it.
tree.insert(0, ET.XML(script))
ET.ElementTree(tree).write('svg_tooltip.svg')
"""
def getSvgScript(self):
return """
<script type="text/ecmascript">
<![CDATA[
function init(evt) {
if ( window.svgDocument == null ) {
svgDocument = evt.target.ownerDocument;
}
}
function ShowTooltip(obj) {
var cur = obj.id.slice(-1);
var tip = svgDocument.getElementById('tooltip_' + cur);
tip.setAttribute('visibility',"visible")
}
function HideTooltip(obj) {
var cur = obj.id.slice(-1);
var tip = svgDocument.getElementById('tooltip_' + cur);
tip.setAttribute('visibility',"hidden")
}
]]>
</script>
"""
def _onMotion(self, event):
visibility_changed = False
for point, annotation in self.annotes:
if event.xdata != None and event.ydata != None: # mouse is inside the axes
should_be_visible = abs(point[0]-event.xdata) < 0.2 and abs(point[1]-event.ydata) < 0.05
if should_be_visible != annotation.get_visible():
visibility_changed = True
annotation.set_visible(should_be_visible)
if visibility_changed:
pl.draw()
def WGrYR(self):
c = mcolors.ColorConverter().to_rgb
seq = [c('white'), c('grey'), 0.33, c('grey'), c('yellow'), 0.66, c('yellow'), c('red')]
seq = [(None,) * 3, 0.0] + list(seq) + [1.0, (None,) * 3]
cdict = {'red': [], 'green': [], 'blue': []}
for i, item in enumerate(seq):
if isinstance(item, float):
r1, g1, b1 = seq[i - 1]
r2, g2, b2 = seq[i + 1]
cdict['red'].append([item, r1, r2])
cdict['green'].append([item, g1, g2])
cdict['blue'].append([item, b1, b2])
#print cdict
return mcolors.LinearSegmentedColormap('Custom_WGrYR', cdict)
ET.register_namespace("","http://www.w3.org/2000/svg")
# test column heat for nodes
n_cols = 5
plot_data = zeros((n_cols,2))
# generate column numbers and random heat values to test
plot_data[:,0] = asarray(arange(1, n_cols+1))#.reshape(n_cols,1)
plot_data[:,1] = random.rand(n_cols,1).reshape(n_cols,)
example = wxToolTipExample(plot_data)
example.plot()
Where am I going wrong?
Your code looks like a work in progress that hasn't been completely cleaned up. (I had to comment out self.tooltip.SetTip() calls to get it to run.) But here is the cause of your immediate issue with the exception you note, and how I found it:
On my machine, I edited backend_svg.py function start() to add a print(extra) and then I run your code. As a result of your lines:
points = ['point_{0}'.format(ii) for ii in arange(1, self.dataX.size+1)]
self.pathCol.set_gid(points)
the matplotlib backend attempts to create an SVG <g> node with the ID: ['point_1', 'point_2', 'point_3', 'point_4', 'point_5']. This is a list, rather than a valid string, so s.replace() fails.
Ultimately you must change your code so that set_gid() only receives string parameters. The simplest way to do that is to change the two lines above to simply:
self.pathCol.set_gid('point_1')
but then you don't get IDs for individual points in the generated SVG. You could also remove the self.pathCol.set_gid line altogether (pathCol it will be rendered to SVG as <g id="PathCollection_1"> and points will also not have IDs).
It appears that it is not simple to assign SVG IDs to individual points/vertices contained within a pathCollection. If you need to do that, you might need to come up with another way to plot them -- if I understand the problem correctly, you'd need to plot individual points rather than a path.
Related
I'm trying to make a 3d scatterplot with fading points over time, similar to this question. However, when I apply the colormap to the data, then the face of the marker changes color but the edge remains solid.
I've tried using the edgecolors='None', edgecolor='none' kwargs, the marker='o' kwarg as per this example, and the edgecolor='face' kwarg. I've also tried using post creation methods such as scat3D.set_edgecolor("None") etc. The first attempts throw an error, and the latter have no effect.
Error from setting kwargs:
Traceback (most recent call last):
File "/home/max/.local/lib/python3.6/site-packages/matplotlib/animation.py", line 230, in saving
yield self
File "/home/max/.local/lib/python3.6/site-packages/matplotlib/animation.py", line 1156, in save
writer.grab_frame(**savefig_kwargs)
File "/home/max/.local/lib/python3.6/site-packages/matplotlib/animation.py", line 384, in grab_frame
dpi=self.dpi, **savefig_kwargs)
File "/home/max/.local/lib/python3.6/site-packages/matplotlib/figure.py", line 2180, in savefig
self.canvas.print_figure(fname, **kwargs)
File "/home/max/.local/lib/python3.6/site-packages/matplotlib/backends/backend_qt5agg.py", line 88, in print_figure
super().print_figure(*args, **kwargs)
File "/home/max/.local/lib/python3.6/site-packages/matplotlib/backend_bases.py", line 2082, in print_figure
**kwargs)
File "/home/max/.local/lib/python3.6/site-packages/matplotlib/backends/backend_agg.py", line 442, in print_raw
FigureCanvasAgg.draw(self)
File "/home/max/.local/lib/python3.6/site-packages/matplotlib/backends/backend_agg.py", line 388, in draw
self.figure.draw(self.renderer)
File "/home/max/.local/lib/python3.6/site-packages/matplotlib/artist.py", line 38, in draw_wrapper
return draw(artist, renderer, *args, **kwargs)
File "/home/max/.local/lib/python3.6/site-packages/matplotlib/figure.py", line 1709, in draw
renderer, self, artists, self.suppressComposite)
File "/home/max/.local/lib/python3.6/site-packages/matplotlib/image.py", line 135, in _draw_list_compositing_images
a.draw(renderer)
File "/home/max/.local/lib/python3.6/site-packages/matplotlib/artist.py", line 38, in draw_wrapper
return draw(artist, renderer, *args, **kwargs)
File "/home/max/.local/lib/python3.6/site-packages/mpl_toolkits/mplot3d/axes3d.py", line 292, in draw
reverse=True)):
File "/home/max/.local/lib/python3.6/site-packages/mpl_toolkits/mplot3d/axes3d.py", line 291, in <lambda>
key=lambda col: col.do_3d_projection(renderer),
File "/home/max/.local/lib/python3.6/site-packages/mpl_toolkits/mplot3d/art3d.py", line 545, in do_3d_projection
ecs = (_zalpha(self._edgecolor3d, vzs) if self._depthshade else
File "/home/max/.local/lib/python3.6/site-packages/mpl_toolkits/mplot3d/art3d.py", line 847, in _zalpha
rgba = np.broadcast_to(mcolors.to_rgba_array(colors), (len(zs), 4))
File "<__array_function__ internals>", line 6, in broadcast_to
File "/home/max/.local/lib/python3.6/site-packages/numpy/lib/stride_tricks.py", line 182, in broadcast_to
return _broadcast_to(array, shape, subok=subok, readonly=True)
File "/home/max/.local/lib/python3.6/site-packages/numpy/lib/stride_tricks.py", line 127, in _broadcast_to
op_flags=['readonly'], itershape=shape, order='C')
ValueError: operands could not be broadcast together with remapped shapes [original->remapped]: (0,4) and requested shape (100,4)
(There's a during the handling the above exception another occured error after that, but my post was flagged as spam so I didn't include it)
Here's the code without the error (adding a kwarg listed above causes the error):
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.animation as animation
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.patches as mpatches
total = 10
num_whatever = 100
to_plot = [np.random.rand(num_whatever, 3) for i in range(total)]
colors = np.linspace(0, 1, num_whatever)
fig = plt.figure()
ax3d = Axes3D(fig)
scat3D = ax3d.scatter([],[],[], s=10, cmap="Blues", vmin=0, vmax=1)
scat3D.set_cmap("Blues") # cmap argument above is ignored, so set it manually
ttl = ax3d.text2D(0.05, 0.95, "", transform=ax3d.transAxes)
def update_plot(i):
print( i, to_plot[i].shape)
ttl.set_text('PCA on 3 components at step = {}'.format(i*20))
scat3D._offsets3d = np.transpose(to_plot[i])
scat3D.set_array(colors)
return scat3D,
def init():
scat3D.set_offsets([[],[],[]])
plt.style.use('ggplot')
ani = animation.FuncAnimation(fig, update_plot, init_func=init,
blit=False, interval=300, frames=range(total))
ani.save("ani.gif", writer="imagemagick")
plt.show()
Here's the plot with the marker edges not hidden:
Plot
You can see that the faded points still have the marker edges not colormapped. I would expect that setting edgecolor would be unnecessary in the first place, since the 2d animation clearly doesn't need it. But why would adding that kwarg cause me to get a operands could not be broadcast togeather error? I don't have any array with shape (0, 4), so it's not clear where this is coming from.
The problem is that if c (as the color argument) is not specified, it is not a priori clear if a colormapping should happen or not. This leads to some internal confusion about which arguments to obey to. But we can specify c as an empty list to get around that.
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.animation as animation
from mpl_toolkits.mplot3d import Axes3D
total = 10
num_whatever = 100
to_plot = [np.random.rand(num_whatever, 3) for i in range(total)]
colors = np.linspace(0, 1, num_whatever)
fig = plt.figure()
ax3d = Axes3D(fig)
scat3D = ax3d.scatter([], [], [], s=10, c=[], cmap="Blues", vmin=0, vmax=1,
depthshade=False)
ttl = ax3d.text2D(0.05, 0.95, "", transform=ax3d.transAxes)
def update_plot(i):
print( i, to_plot[i].shape)
ttl.set_text('PCA on 3 components at step = {}'.format(i*20))
scat3D._offsets3d = np.transpose(to_plot[i])
scat3D.set_array(colors)
return scat3D,
def init():
scat3D.set_offsets([[],[],[]])
plt.style.use('ggplot')
ani = animation.FuncAnimation(fig, update_plot, init_func=init,
blit=False, interval=300, frames=range(total))
ani.save("ani.gif", writer="imagemagick")
plt.show()
I have the following code snippet to illustrate the issue:
import matplotlib
matplotlib.use('TkAgg')
import matplotlib.pyplot as plt
import time
import random
# Mock categories
categories = ["cat1", "cat2", "cat3", "cat4"]
counter = 0
# Plot
x_data = []
y_data = []
plt.ion()
fig = plt.figure()
subplt = fig.add_subplot(312)
subplt_line, = subplt.plot(x_data, y_data, 'b.')
while True:
time.sleep(0.1) # simulate some delay that occurs in the actual application
x_data.append(counter)
subplt_line.set_xdata(x_data)
counter += 1
# y_data.append(random.randrange(1, 15)) # This works fine (except the scaling)
y_data.append(random.choice(categories)) # This will end in an exception
subplt_line.set_ydata(y_data)
# Update the plot
fig.canvas.draw()
fig.canvas.flush_events()
It will end in an exception like this:
Traceback (most recent call last):
File "test.py", line 36, in <module>
fig.canvas.draw()
File "/anaconda3/envs/xxx/lib/python2.7/site-packages/matplotlib/backends/backend_tkagg.py", line 12, in draw
super(FigureCanvasTkAgg, self).draw()
File "/anaconda3/envs/xxx/lib/python2.7/site-packages/matplotlib/backends/backend_agg.py", line 437, in draw
self.figure.draw(self.renderer)
File "/anaconda3/envs/xxx/lib/python2.7/site-packages/matplotlib/artist.py", line 55, in draw_wrapper
return draw(artist, renderer, *args, **kwargs)
File "/anaconda3/envs/xxx/lib/python2.7/site-packages/matplotlib/figure.py", line 1493, in draw
renderer, self, artists, self.suppressComposite)
File "/anaconda3/envs/xxx/lib/python2.7/site-packages/matplotlib/image.py", line 141, in _draw_list_compositing_images
a.draw(renderer)
File "/anaconda3/envs/xxx/lib/python2.7/site-packages/matplotlib/artist.py", line 55, in draw_wrapper
return draw(artist, renderer, *args, **kwargs)
File "/anaconda3/envs/xxx/lib/python2.7/site-packages/matplotlib/axes/_base.py", line 2635, in draw
mimage._draw_list_compositing_images(renderer, self, artists)
File "/anaconda3/envs/xxx/lib/python2.7/site-packages/matplotlib/image.py", line 141, in _draw_list_compositing_images
a.draw(renderer)
File "/anaconda3/envs/xxx/lib/python2.7/site-packages/matplotlib/artist.py", line 55, in draw_wrapper
return draw(artist, renderer, *args, **kwargs)
File "/anaconda3/envs/xxx/lib/python2.7/site-packages/matplotlib/lines.py", line 738, in draw
self.recache()
File "/anaconda3/envs/xxx/lib/python2.7/site-packages/matplotlib/lines.py", line 656, in recache
yconv = self.convert_yunits(self._yorig)
File "/anaconda3/envs/xxx/lib/python2.7/site-packages/matplotlib/artist.py", line 200, in convert_yunits
return ax.yaxis.convert_units(y)
File "/anaconda3/envs/xxx/lib/python2.7/site-packages/matplotlib/axis.py", line 1526, in convert_units
ret = self.converter.convert(x, self.units, self)
File "/anaconda3/envs/xxx/lib/python2.7/site-packages/matplotlib/category.py", line 65, in convert
unit.update(values)
AttributeError: 'NoneType' object has no attribute 'update'
I seems like the combination of categorcal y data and the interactivity is causing this. When using numerical values it works fine, and when using the non-interactive feature it works well even with the categorical axis.
Another issue is be the automatic scaling of the y axis. New values added via set_y_data() dot seem to trigger this.
The plot will visualize analysis done on an endless stream of data and is used like a dashboard - therefore the plot should update with each iteration of the loop.
I couldn't run your code using the while loop, but I would suggest using FuncAnimation to create self-updating graphs anyway (there are plenty of examples on SO and online).
I believe your problem is with the initialization of the Line2D object. When you're passing any empty y-array, matplotlib seem to assume you're going to use numerical and not categorical values. Initializing the line with a string as a y-value seem to do the trick. You'll have to adjust the code so that the first point created makes sense for your data, but that should only be a minor annoyance.
For the scaling of the axis, matplotlib adds each category to a new integer value, so you need only to count how many categories you have in your data to know what is the extent of the axes.
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.animation as animation
import random
# Mock categories
categories = ["cat1", "cat2", "cat3", "cat4"]
counter = 0
# Plot
x_data = [0]
y_data = ['cat1']
fig = plt.figure()
subplt = fig.add_subplot(312)
subplt_line, = subplt.plot(x_data, y_data, 'b.-')
debug_text = fig.text(0, 1, "TEXT", va='top') # for debugging
def init():
subplt_line.set_data([0],['cat1'])
def animate(num, ax):
new_x, new_y = num, random.choice(categories)
debug_text.set_text('{:d} {:s}'.format(num, new_y))
x, y = subplt_line.get_data()
x = np.append(x, new_x)
y = np.append(y, new_y)
subplt_line.set_data(x,y)
ax.set_xlim(min(x),max(x))
ax.set_ylim(0,len(np.unique(y))-1)
return subplt_line,debug_text
ani = animation.FuncAnimation(fig, animate, fargs=[subplt], init_func=init, frames=20, blit=False, repeat=False)
plt.show()
I've got some polygons in RA/Dec spherical coordinates, and I'm trying to plot them with aplpy and an astropy world coordinate system (WCS) object, but my script crashes.
I can reproduce the problem with this standalone script:
#!/usr/bin/env python
import astropy
import aplpy, numpy
from numpy import array
import matplotlib.pyplot as plt
from matplotlib import cm, colors
from astropy.wcs import WCS
cent_ra = 1 # plot center, ra, deg
cent_dec = 88 # plot center, dec, deg
rad = 7 # plot radius, deg
rad_pix = 300 # plot radius, pixels
# two polygons to plot, in ra-dec space
polygons_radec = [ array([[ 1.0, 88.0],[ 2.0, 88.0],[ 2.0, 89.0],[ 1.0, 88.0]]),
array([[ 1.0, 88.0],[ 2.0, 88.0],[ 2.0, 87.0],[ 1.0, 88.0]]) ]
zvalues = [5,2]
# setup our radec-pixel coordinate transformation
w = WCS( naxis=2 )
w.naxis1 = 2 * rad_pix
w.naxis2 = 2 * rad_pix
w.wcs.crpix = [rad_pix, rad_pix] # reference pixel
w.wcs.crval = [ cent_ra, cent_dec ] # reference pixel's ra/dec coordinate?
w.wcs.cdelt = array([ rad/rad_pix, rad/rad_pix ]) # pixel delta in ra/dec space?
w.wcs.ctype = ['RA--TAN','DEC-TAN']
# convert the ra-dec polygon coordinates to pixel coordinates
polygons = []
for p in polygons_radec :
polygon = []
for c in p :
polygon += [ w.wcs_world2pix( c[0], c[1], 1 ) ]
polygons += [ array( polygon ) ]
print('polygons:')
print(polygons)
print()
# plot our polygons with colors
cmap1 = cm.YlOrBr
norm1 = colors.Normalize( numpy.min(zvalues), numpy.max(zvalues) )
fig = aplpy.FITSFigure( w )
for p, c in zip( polygons, zvalues ) :
fig.show_polygons( [p], facecolor=cmap1(norm1(c)), edgecolor='none', alpha=0.3 )
plt.savefig( 'plot.png' , dpi=300 )
When I try to run this, I get a rather large traceback/exception:
Traceback (most recent call last):
File "./test.py", line 46, in <module>
plt.savefig( 'plot.png' , dpi=300 )
File "/.../miniconda3/lib/python3.5/site-packages/matplotlib/pyplot.py", line 696, in savefig
res = fig.savefig(*args, **kwargs)
File "/.../miniconda3/lib/python3.5/site-packages/matplotlib/figure.py", line 1563, in savefig
self.canvas.print_figure(*args, **kwargs)
File "/.../miniconda3/lib/python3.5/site-packages/matplotlib/backends/backend_qt5agg.py", line 203, in print_figure
FigureCanvasAgg.print_figure(self, *args, **kwargs)
File "/.../miniconda3/lib/python3.5/site-packages/matplotlib/backend_bases.py", line 2232, in print_figure
**kwargs)
File "/.../miniconda3/lib/python3.5/site-packages/matplotlib/backends/backend_agg.py", line 527, in print_png
FigureCanvasAgg.draw(self)
File "/.../miniconda3/lib/python3.5/site-packages/matplotlib/backends/backend_agg.py", line 474, in draw
self.figure.draw(self.renderer)
File "/.../miniconda3/lib/python3.5/site-packages/matplotlib/artist.py", line 62, in draw_wrapper
draw(artist, renderer, *args, **kwargs)
File "/.../miniconda3/lib/python3.5/site-packages/matplotlib/figure.py", line 1159, in draw
func(*args)
File "/.../miniconda3/lib/python3.5/site-packages/mpl_toolkits/axes_grid1/parasite_axes.py", line 295, in draw
self._get_base_axes_attr("draw")(self, renderer)
File "/.../miniconda3/lib/python3.5/site-packages/mpl_toolkits/axisartist/axislines.py", line 772, in draw
super(Axes, self).draw(renderer, inframe)
File "/.../miniconda3/lib/python3.5/site-packages/matplotlib/artist.py", line 62, in draw_wrapper
draw(artist, renderer, *args, **kwargs)
File "/.../miniconda3/lib/python3.5/site-packages/matplotlib/axes/_base.py", line 2319, in draw
a.draw(renderer)
File "/.../miniconda3/lib/python3.5/site-packages/matplotlib/artist.py", line 62, in draw_wrapper
draw(artist, renderer, *args, **kwargs)
File "/.../miniconda3/lib/python3.5/site-packages/matplotlib/axis.py", line 1108, in draw
ticks_to_draw = self._update_ticks(renderer)
File "/.../miniconda3/lib/python3.5/site-packages/matplotlib/axis.py", line 951, in _update_ticks
tick_tups = [t for t in self.iter_ticks()]
File "/.../miniconda3/lib/python3.5/site-packages/matplotlib/axis.py", line 951, in <listcomp>
tick_tups = [t for t in self.iter_ticks()]
File "/.../miniconda3/lib/python3.5/site-packages/matplotlib/axis.py", line 898, in iter_ticks
for i, val in enumerate(majorLocs)]
File "/.../miniconda3/lib/python3.5/site-packages/matplotlib/axis.py", line 898, in <listcomp>
for i, val in enumerate(majorLocs)]
File "/.../miniconda3/lib/python3.5/site-packages/aplpy/labels.py", line 421, in __call__
label = self.axis.apl_tick_spacing * self.axis.apl_tick_positions_world[ipos]
File "/.../miniconda3/lib/python3.5/site-packages/aplpy/angle_util.py", line 242, in __mul__
s = Angle(sexagesimal=(d, m, s), latitude=self.latitude)
File "/.../miniconda3/lib/python3.5/site-packages/aplpy/angle_util.py", line 52, in __init__
self._simplify()
File "/.../miniconda3/lib/python3.5/site-packages/aplpy/angle_util.py", line 88, in _simplify
degrees")
Exception: latitude should be between -90 and 90
The plot overlaps one of the spherical coordinate system's poles (Declination=90 deg), so I'm wondering if that's causing a problem/revealing a bug, or if its because I've set up my WCS incorrectly.
How can I get the polygons to show up?
I am trying to make a 3d line chart with matplotlib in python. The data set is taken from a measuring station with different sensors. Now i have the code pretty much as i want it, but every time i try to run it it shows this problem:
TypeError: Cannot cast array data from dtype('float64') to dtype('S32') according to the rule 'safe'
My code so far:
import csv
from mpl_toolkits.mplot3d import axes3d
import matplotlib.pyplot as plt
depth = {
1 : 11, 2 : 35, 3 : -1, 4 : 11, #position of graphs in cm
}
class SetXYZ:
def __init__(self, datalist, NameNum): #datalist: list with data, NameNum: number of variable
self.NameNum = NameNum
self.datalist = datalist
self.Name = datalist[0][NameNum]
self.length = datalist
def X(self): #Creates list with X Variables
Xlist = []
for element in self.datalist:
Xlist.append(element[0])
Xlist.pop(0)
return Xlist
def Y(self): #Creates list with Y Variables
Ylist = []
for element in self.datalist:
Ylist.append(element[self.NameNum])
Ylist.pop(0)
return Ylist
def Z(self): #list with Z variables
Zlist = []
for element in datalist: #Z is the same for every point on one graph
Zlist.append(depth[self.NameNum-1])
Zlist.pop(0)
return Zlist
def csv_to_list(filename): #returns the file as list
with open(filename, 'rb') as data:
data = csv.reader(data, delimiter=';')
datalist = list(data)
return datalist
filename = " " #Filename
datalist = csv_to_list(filename)
Graph1 = SetXYZ(datalist, 1) #creates the graphs
Graph2 = SetXYZ(datalist, 2)
#plots a graph, more or less to test
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.scatter(Graph1.X(), Graph1.Y(), Graph1.Z())
plt.show()
a file looks like this:
Time; sensor 1; sensor 2; sensor 3; sensor4
41940.6791666667;16;19.96;4.1;11.52
41940.67986;15.9;20.51;4.07;11.4
41940.67986;15.9;20.53;4.07;11.41
The full error looks like this:
Traceback (most recent call last):
File "C:\Anaconda\lib\site-packages\matplotlib\backends\backend_qt5.py", line 338, in resizeEvent
self.draw()
File "C:\Anaconda\lib\site-packages\matplotlib\backends\backend_qt5agg.py", line 148, in draw
FigureCanvasAgg.draw(self)
File "C:\Anaconda\lib\site-packages\matplotlib\backends\backend_agg.py", line 461, in draw
self.figure.draw(self.renderer)
File "C:\Anaconda\lib\site-packages\matplotlib\artist.py", line 59, in draw_wrapper
draw(artist, renderer, *args, **kwargs)
File "C:\Anaconda\lib\site-packages\matplotlib\figure.py", line 1079, in draw
func(*args)
File "C:\Anaconda\lib\site-packages\mpl_toolkits\mplot3d\axes3d.py", line 254, in draw
for col in self.collections]
File "C:\Anaconda\lib\site-packages\mpl_toolkits\mplot3d\art3d.py", line 413, in do_3d_projection
vxs, vys, vzs, vis = proj3d.proj_transform_clip(xs, ys, zs, renderer.M)
File "C:\Anaconda\lib\site-packages\mpl_toolkits\mplot3d\proj3d.py", line 208, in proj_transform_clip
return proj_transform_vec_clip(vec, M)
File "C:\Anaconda\lib\site-packages\mpl_toolkits\mplot3d\proj3d.py", line 165, in proj_transform_vec_clip
vecw = np.dot(M, vec)
TypeError: Cannot cast array data from dtype('float64') to dtype('S32') according to the rule 'safe'
When it is finished there can be up to 30 sensors and several thousand times.
Is there a workaround to this, or what am i doing wrong?
Thanks for your help!
My problem is following:
I'm taking a data from files and want to make an animation of four plots at the same time: two colourbars and two lines.
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as anim
import sys
begin = float(sys.argv[1])
end = float(sys.argv[2])
dataCl = np.loadtxt("file1.txt")
dataSS = np.loadtxt("file2.txt")
datajSR = np.loadtxt("file3.txt")
ibegin = 0
iend = 0
for i in range(len(dataCl[:,0])):
if np.abs(dataCl[i,0] - begin) < 1e-9:
ibegin = i
iend = i
while abs(dataCl[i,0] - end) >= 1e-9:
iend = iend + 1
i = i + 1
break
fig = plt.figure()
f, axarr = plt.subplots(2, 2)
temp = np.zeros((10,10))
Qs = axarr[0,0].imshow(temp,cmap = plt.cm.OrRd)
El = axarr[0,1].imshow(temp,cmap = plt.cm.OrRd)
SS, = axarr[1,0].plot([],[])
jSR, = axarr[1,1].plot([],[])
def init():
Qs.set_array(temp)
El.set_array(temp)
SS.set_data([],[])
jSR.set_data([],[])
return Qs,El,SS,jSR,
def animate(i):
a = 0
b = 0
dataQ = np.zeros((10,10))
dataE = np.zeros((10,10))
for j in range(100):
if b >= 10:
a = a + 1
b = 0
dataQ[a][b] = dataCl[i,2*j + 1]
dataE[a][b] = dataCl[i,2*(j+1)]
b = b + 1
Qs.set_array(dataQ)
El.set_array(dataE)
SS.set_data(dataSS[ibegin:ibegin+i,0],dataSS[ibegin:ibegin+i,1])
jSR.set_data(datajSR[ibegin:ibegin+i,0],datajSR[ibegin:ibegin+i,1])
return Qs,El,SS,jSR,
ani = anim.FuncAnimation(fig, animate, init_func = init, frames = iend-ibegin,interval=25, blit=True)
plt.show()
After running it shows these messages:
Exception in Tkinter callback
Traceback (most recent call last):
File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 1413, in __call__
return self.func(*args)
File "/usr/lib/pymodules/python2.7/matplotlib/backends/backend_tkagg.py", line 236, in resize
self.show()
File "/usr/lib/pymodules/python2.7/matplotlib/backends/backend_tkagg.py", line 239, in draw
FigureCanvasAgg.draw(self)
File "/usr/lib/pymodules/python2.7/matplotlib/backends/backend_agg.py", line 421, in draw
self.figure.draw(self.renderer)
File "/usr/lib/pymodules/python2.7/matplotlib/artist.py", line 55, in draw_wrapper
draw(artist, renderer, *args, **kwargs)
File "/usr/lib/pymodules/python2.7/matplotlib/figure.py", line 904, in draw
self.canvas.draw_event(renderer)
File "/usr/lib/pymodules/python2.7/matplotlib/backend_bases.py", line 1544, in draw_event
self.callbacks.process(s, event)
File "/usr/lib/pymodules/python2.7/matplotlib/cbook.py", line 262, in process
proxy(*args, **kwargs)
File "/usr/lib/pymodules/python2.7/matplotlib/cbook.py", line 192, in __call__
return mtd(*args, **kwargs)
File "/usr/lib/pymodules/python2.7/matplotlib/animation.py", line 273, in _end_redraw
self._post_draw(None, self._blit)
File "/usr/lib/pymodules/python2.7/matplotlib/animation.py", line 220, in _post_draw
self._blit_draw(self._drawn_artists, self._blit_cache)
File "/usr/lib/pymodules/python2.7/matplotlib/animation.py", line 235, in _blit_draw
a.axes.draw_artist(a)
File "/usr/lib/pymodules/python2.7/matplotlib/axes.py", line 2008, in draw_artist
assert self._cachedRenderer is not None
AssertionError
I cannot find a mistake in my code ;(
The error message might be backend and platform specific. As the error message seems to point to the blitting mechanism, you might want to try setting blit=False in FuncAnimation. Also, you might try some other backend to see if the problem persists. (Knowing your platform and matplotlib version might also help.)
Update: If setting blit=False, trying another backend, and updating matplotlib does not help, then a few suggestions:
Try to see manually if you code works with the initial data (init(); animate(0); fig.savefig("/tmp/test.png")) - if it throws an error, there is a static plotting problem to fix.
Now you initialize the plot twice (first in the code, then in init), you can take one away (e.g. do not define init_func)
Initializing the plots with [],[] leaves the scale uninitialized. You should probably use set_ylim, set_xlim with the plots and vmin, vmax keywords with the imshow images when you initialize them. (This could possibly have something to do with the exception you get!)