This issue seems to happen any time I plot data using plt.show() with Matplotlib on my Macbook Pro (OSX 10.13.6). If I create a Pandas dataframe and plot the data with Matplotlib, then show the result on the screen in the interactive window (using plt.show), the window (and matplotlib) will often crash. It will always happen if the mouse gesture for scroll-up or down is done on the screen. Other times it seems to happen at random.
When the plot crashes i get this as a traceback:
Traceback (most recent call last):
File "./plot_lc_vs_gnss.py", line 117, in <module>
main()
File "./plot_lc_vs_gnss.py", line 28, in main
plt.show()
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/matplotlib/pyplot.py", line 253, in show
return _show(*args, **kw)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/matplotlib/backend_bases.py", line 208, in show
cls.mainloop()
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/matplotlib/backends/_backend_tk.py", line 1073, in mainloop
Tk.mainloop()
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/tkinter/__init__.py", line 557, in mainloop
_default_root.tk.mainloop(n)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 0: invalid start byte
The data I am reading in is a simple CSV that was previously generated by pandas as well. I am generating the plot with a simple script like this:
#!/usr/local/bin/python3
import matplotlib
matplotlib.use('TkAgg')
import json
import os
import numpy as np
import pandas as pd
import pymap3d as pm
import matplotlib.pyplot as plt
def load_csvs():
gnss = pd.read_csv('di3_d4_1017_gnss.csv')
ins = pd.read_csv('di3_d4_1017_ins.csv')
return gnss, ins
def plot_cdf(gnss, ins):
data = [gnss, ins]
plt.figure(figsize=[12,9])
ax = plt.subplot(1,1,1)
for ds in data:
if ds[err].any != np.nan:
dsorted = np.sort(ds['horizontal_error'])
yvals = np.arange(len(dsorted)) / float(len(dsorted) - 1) * 100
ax.plot(dsorted, yvals)
ax.grid()
ax.set_xlabel('Horizontal Error (m)')
ax.set_ylabel('Percent of Epochs')
title = 'Drive Test data \n DI-3 (roof) d4_1017 \n CDF Horizontal Error'
plt.title(title)
plt.legend(['gnss', 'ins'], loc='lower right')
def main():
gnss, ins = load_csvs()
plot_cdf(gnss, ins)
plt.show()
if __name__ == "__main__":
main()
Any advice on how to fix this issue would be greatly appreciated.
I guess by now it does not matter, but this seems to be an unresolved problem under discussion in #9637
Related
The mpld3 (matplotlib on d3) example for LinkedBrush
http://mpld3.github.io/examples/linked_brush.html provides the following code example:
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
import mpld3
from mpld3 import plugins, utils
data = load_iris()
X = data.data
y = data.target
# dither the data for clearer plotting
X += 0.1 * np.random.random(X.shape)
fig, ax = plt.subplots(4, 4, sharex="col", sharey="row", figsize=(8, 8))
fig.subplots_adjust(left=0.05, right=0.95, bottom=0.05, top=0.95,
hspace=0.1, wspace=0.1)
for i in range(4):
for j in range(4):
points = ax[3 - i, j].scatter(X[:, j], X[:, i],
c=y, s=40, alpha=0.6)
# remove tick labels
for axi in ax.flat:
for axis in [axi.xaxis, axi.yaxis]:
axis.set_major_formatter(plt.NullFormatter())
# Here we connect the linked brush plugin
plugins.connect(fig, plugins.LinkedBrush(points))
mpld3.show()
While the public web page shows the matrix of linked outputs, when running it locally there is a json serialization error:
Traceback (most recent call last):
File "/git/scalatesting/src/main/python/mpld3_linkedbrush.py", line 34, in <module>
mpld3.show()
File "/usr/local/lib/python2.7/site-packages/mpld3/_display.py", line 358, in show
html = fig_to_html(fig, **kwargs)
File "/usr/local/lib/python2.7/site-packages/mpld3/_display.py", line 251, in fig_to_html
figure_json=json.dumps(figure_json, cls=NumpyEncoder),
File "/usr/local/Cellar/python/2.7.14/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/__init__.py", line 251, in dumps
sort_keys=sort_keys, **kw).encode(obj)
File "/usr/local/Cellar/python/2.7.14/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/encoder.py", line 207, in encode
chunks = self.iterencode(o, _one_shot=True)
File "/usr/local/Cellar/python/2.7.14/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/encoder.py", line 270, in iterencode
return _iterencode(o, 0)
File "/usr/local/lib/python2.7/site-packages/mpld3/_display.py", line 138, in default
return json.JSONEncoder.default(self, obj)
File "/usr/local/Cellar/python/2.7.14/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/encoder.py", line 184, in default
raise TypeError(repr(o) + " is not JSON serializable")
TypeError: array([ 1.]) is not JSON serializable
The local environment is
$pip show mpld3
Name: mpld3
Version: 0.3
Summary: D3 Viewer for Matplotlib
Home-page: http://mpld3.github.com
Author: Jake VanderPlas
Author-email: jakevdp#cs.washington.edu
License: BSD 3-clause
Location: /usr/local/lib/python2.7/site-packages
and
$python -V
Python 2.7.14
The mpld3 was installed today. Is there an mpld3 versioning issue? Any other suggestions?
Based on a comment from #snakecharmerb I forked from mpld3, entered the suggested fix, and pip installed from my new branch on github.
The fix is here: https://github.com/javadba/mpld3/tree/display_fix . It may be installed via:
python -m pip install --user "git+https://github.com/javadba/mpld3#display_fix"
It works well: the json serialization error is gone and the linkage among the 9 charts functions properly:
For me, the solution given here did not work.
I had a networkx graph to visualize:
import matplotlib.pyplot as plt
import numpy as np
import mpld3
import networkx as nx
G = nx.path_graph(4)
pos = nx.spring_layout(G)
fig, ax = plt.subplots(subplot_kw=dict(facecolor='#EEEEEE'))
scatter = nx.draw_networkx_nodes(G, pos, ax=ax)
nx.draw_networkx_edges(G, pos, ax=ax)
labels = G.nodes()
tooltip = mpld3.plugins.PointLabelTooltip(scatter, labels=labels)
mpld3.plugins.connect(fig, tooltip)
mpld3.show()
Then it gave the "JSON not serializable" error. I found the above link, and tried the fix. The fix essentially says that if the object is of type numpy.ndarray, then change it to list.
But the object type of G.nodes is networkx.classes.reportviews.NodeView, not numpy.ndarray; thus it wasn't working.
So, I modified the file _display.py to add import networkx and added the following 2 lines in the default function in class NumpyEncoder to make it work:
elif isinstance(obj,networkx.classes.reportviews.NodeView):
return list(obj)
Now it works:
The codes are as below:
import tushare as ts
import matplotlib.pyplot as plt
from matplotlib.finance import candlestick_ohlc as candle
stock=ts.get_hist_data('000581',ktype='w')
the data form of "stock" is as below picture:
enter image description here
Then the below codes:
vals=stock.iloc[:,0:4]
fig=plt.figure()
ax=fig.add_subplot(111)
candle(ax,vals)
I get error as below:
Traceback (most recent call last):
File "", line 1, in
File "/usr/local/anaconda3/lib/python3.5/site-packages/matplotlib/finance.py", line 735, in candlestick_ohlc
alpha=alpha, ochl=False)
File "/usr/local/anaconda3/lib/python3.5/site-packages/matplotlib/finance.py", line 783, in _candlestick
t, open, high, low, close = q[:5]
ValueError: not enough values to unpack (expected 5, got 4)
How shall I resove it?
candlestick needs a very specific format and order to work. For example, if you use _ohlc, then the order must be open-high-low-close. The array for the candlestick graph can be prepared as follows:
candleArray = []
while i < len(datep):
newLine = datep[i], openp[i], highp[i], lowp[i], closep[i], volumep[i], pricechange[i], pchange[i]
candleArray.append(newLine)
i += 1
Then, you can call candlestick with the array candleArray.
I am trying to plot a contour plot with Python's Matplotlib package. I'm trying to get similar results to what can be seen in this other stack overflow post. However, I'm getting the problem of it saying that there is a type error and it tells me TypeError: Invalid dimensions for image data, which can be seen in the full error code below.
Traceback (most recent call last):
File "./plot_3.py", line 68, in <module>
plt.imshow(zi, vmin=temp.min(), vmax=temp.max(), origin="lower", extent=[x.min(), x.max(), y.min(), y.max()])
File "/usr/lib64/python2.7/site-packages/matplotlib/pyplot.py", line 3022, in imshow
**kwargs)
File "/usr/lib64/python2.7/site-packages/matplotlib/__init__.py", line 1812, in inner
return func(ax, *args, **kwargs)
File "/usr/lib64/python2.7/site-packages/matplotlib/axes/_axes.py", line 4947, in imshow
im.set_data(X)
File "/usr/lib64/python2.7/site-packages/matplotlib/image.py", line 453, in set_data
raise TypeError("Invalid dimensions for image data")
TypeError: Invalid dimensions for image data
I'm unsure of what this means, as googling brought up no useful results on how to fix it. The code is listed below, and the data that I'm using can be found here. The code below simply runs the code which will parse the file and then return the data to the main where it's supposed to plot it then. To run the code, you have to use ./plot_3.py 20.0 to use it with the specific file that I posted above. x ranges from 0 to 0.3 with 61 grids, while y ranges from 0 to 0.4 with 81 grids. The data is in the format x,y,temperature where I want the temperature values to be the contour values.
from __future__ import print_function, division
import math
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
import sys
import matplotlib.cm as cm
from matplotlib.mlab import griddata
import scipy.interpolate
def ParseFile(filename):
x = []
y = []
temp = []
infile = open(filename, 'r')
lines = [line.strip() for line in infile.readlines()]
for line in lines:
x.append(float(line.split(',')[0]))
y.append(float(line.split(',')[1]))
temp.append(float(line.split(',')[2]))
return np.array(x), np.array(y), np.array(temp)
time = str(sys.argv[1])
filename = time + "_sec.dat"
x,y,temp = ParseFile(filename)
xi = np.linspace(min(x), max(x))
yi = np.linspace(min(y), max(y))
zi = scipy.interpolate.griddata((x,y),temp,(xi,yi),method="linear")
matplotlib.rcParams['xtick.direction'] = 'out'
matplotlib.rcParams['ytick.direction'] = 'out'
plt.imshow(zi, vmin=temp.min(), vmax=temp.max(), origin="lower",
extent=[x.min(), x.max(), y.min(), y.max()])
plt.colorbar()
plt.show()
I think the problem is that that you need to have the points to be interpolated in a gridded format, not two 1D matrices for the interpolate.griddata function.
Adding this line to the (xi, yi) declaration I think fixes your problem:
x,y,temp = ParseFile(filename)
xi = np.linspace(min(x), max(x))
yi = np.linspace(min(y), max(y))
#create the 2D grid for interpolation:
xi, yi = np.meshgrid(xi,yi)
zi = scipy.interpolate.griddata((x,y),temp,(xi,yi),method="linear")
I'm pretty new to using matplotlib and seaborn, and I couldn't really find any "for dummies" guides on how to do this. I keep getting error messages trying to use code from the guides I can find. I guess I'm having difficulty taking their pieces of code and knowing how to apply it to my problem.
I'd like to make a plot like the ones here: 1 and 2. I have a data file with two columns of data ranging from -180 to 180.
This is my attempt at the code:
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
from scipy.stats import kendalltau
sns.set(style="ticks")
f2 = open("dihs23")
lines = f2.readlines()
f2.close()
x = []
y = []
for line in lines:
p = line.split()
x.append(float(p[0]))
y.append(float(p[1]))
sns.jointplot(x, y, kind="hex", stat_func=kendalltau, color="#4CB391")
sns.plt.show()
Which returns the error
Traceback (most recent call last):
File "heatmap.py", line 30, in <module>
sns.jointplot(x, y, kind="hex", stat_func=kendalltau, color="#4CB391")
File "/usr/local/lib/python2.7/dist-packages/seaborn/distributions.py", line 973, in jointplot
xlim=xlim, ylim=ylim)
File "/usr/local/lib/python2.7/dist-packages/seaborn/axisgrid.py", line 1133, in __init__
x = x[not_na]
TypeError: only integer arrays with one element can be converted to an index
I'm guessing there's some aspect to the format of the data that is part of the problem, but I'm not sure how to fix it.
Thank you for the help!
Try transforming your lists to an array with NumPy
x_axis = np.asarray(x)
y_axis = np.asarray(y)
I really like the idea that cartopy can automatically plot in different map projections. However, I couldn't figure out how to do with the Iris cubes. As its a sister project, I expected that I might be able to. Is it possible to do something like this?
import iris as I
import cartopy.crs as ccrs
import matplotlib.pyplot as plt
someCube = I.load('someCube.pp')
ax = plt.axes(projection=ccrs.Robinson())
I.plot.contourf(someCube, transform=ccrs.Robinson())
plt.show()
thanks
I took your pseudo code and made it runnable with Iris' sample data:
import iris
import iris.plot as iplt
import cartopy.crs as ccrs
import matplotlib.pyplot as plt
fname = iris.sample_data_path('air_temp.pp')
air_temp = iris.load_cube(fname)
ax = plt.axes(projection=ccrs.Robinson())
iplt.contourf(air_temp, transform=ccrs.Robinson(central_longitude=180))
ax.coastlines()
plt.show()
If you run this code, you will get an exception along the lines of:
Traceback (most recent call last):
File "using_custom_projections.py", line 11, in <module>
iris.plot.contourf(air_temp, transform=ccrs.Robinson())
File "lib/iris/plot.py", line 452, in contourf
result = _draw_2d_from_points('contourf', None, cube, *args, **kwargs)
File "lib/iris/plot.py", line 263, in _draw_2d_from_points
result = _map_common(draw_method_name, arg_func, iris.coords.POINT_MODE, cube, data, *args, **kwargs)
File "lib/iris/plot.py", line 406, in _map_common
assert 'transform' not in kwargs, 'Transform keyword is not allowed.'
AssertionError: Transform keyword is not allowed.
Which is trying to tell you that you do not need to tell it which "transform" (or coordinate system) the cube is in. The reason for that is that an Iris cube should contain full metadata about the underlying data: the coordinate systems is part of that metadata.
So, to get the example to work, you can simply remove the transform keyword argument in your contourf call:
import iris
import iris.plot as iplt
import cartopy.crs as ccrs
import matplotlib.pyplot as plt
fname = iris.sample_data_path('air_temp.pp')
air_temp = iris.load_cube(fname)
ax = plt.axes(projection=ccrs.Robinson(central_longitude=180))
iplt.contourf(air_temp)
ax.coastlines()
plt.show()
There is a similar example in the iris gallery, specifically http://scitools.org.uk/iris/docs/latest/examples/graphics/rotated_pole_mapping.html#rotated-pole-mapping-03 (the very last plot in the example).
HTH,