I am new to python Django framework.
I have matplotlib moving or live chart, It should be embedded in django template. I checked many question relevant to this here but none of them is worked for me. Most of us suggested here is displaying as image, but problem is moving chart with default interface like zoom, drag everything to be integrated.
i am struggling to solve . I used this code and got to know it will be displaying as image.
def simple(request):
import random
import django
import datetime
from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
from matplotlib.figure import Figure
from matplotlib.dates import DateFormatter
fig = Figure()
ax = fig.add_subplot(111)
x = []
y = []
now = datetime.datetime.now()
delta = datetime.timedelta(days=1)
for i in range(10):
x.append(now)
now += delta
y.append(random.randint(0, 1000))
ax.plot_date(x, y, '-')
ax.xaxis.set_major_formatter(DateFormatter('%Y-%m-%d'))
fig.autofmt_xdate()
canvas = FigureCanvas(fig)
response = django.http.HttpResponse(content_type='image/png')
canvas.print_png(response)
return response
I used this code for reference.
if this is not understandable please comment below, ill try to convey you clearly
can any one help me to get fixed this. Thanks in advance.
Instead of doing with matplotlib you can try with BOKEH chart. check this out Bokeh charts doc
While it may seem like a simple question, the machinery that matplotlib employs to present an interactive chart on desktop is reasonably complex, and not something one can just drop in to some HTML somewhere.
I would suggest you look at a frontend library for graphically displaying data, then provide your frontend the data with your backend.
As for libraries, check out C3. It's got good docs and examples.
Related
I am using interactive python with plt.ion() for generating figures (v2.7) and have noticed that the figure looks different from the figure exported by savefig (this is not a DPI issue (cf. matplotlib savefig() plots different from show()) - I think it might be a backend issue, but would appreciate help as I don't understand this properly).
Specifically, I wanted visualise the importance of a series of points by the intensity of their colour, which I thought I could do with the "alpha" keyword in matplotlib.
When I just do this, this works fine,
but when I want to add a line to the figure, the alpha keyword seemed to not work any more, and plt.ion() shows this:
I initially thought that perhaps the following issue on github may be related:
https://github.com/matplotlib/matplotlib/issues/4580
but then I noticed that exporting the figure actually produced the following file (i.e. as desired):
It would be great to understand a bit better what is going on, and how I can avoid such issues in the future. Is plt.ion()/plt.show() not the best way to show figures in interactive python, or is this an issue with the alpha keyword?
The code is here:
import numpy as np
from numpy import random as random
from matplotlib import pyplot as plt
fig2,ax2=plt.subplots(1,1,figsize=(3,3),sharey=True)
for ii in range(1):
ax2.plot(np.linspace(0,200,200), [0.1]*200, c= 'k')
for i in range(200):
test2=random.randint(5)
ydata= random.rand(test2)
test = random.rand(test2)
for j in range(test2):
ax2.plot(i,ydata[j],'o',ms=4, c= 'Darkblue',alpha=test[j],markeredgecolor='None')
I am experimenting with time plots such as this example from bokeh. Is it possible to create minor ticks for the x-axis? I tried all the different options inside p.xaxis.minor but none seemed useful.
Here's the code from example:
import pandas as pd
from bokeh.plotting import figure, output_file, show
AAPL = pd.read_csv(
"http://ichart.yahoo.com/table.csv?s=AAPL&a=0&b=1&c=2000&d=0&e=1&f=2010",
parse_dates=['Date']
)
output_file("datetime.html")
# create a new plot with a datetime axis type
p = figure(width=800, height=250, x_axis_type="datetime")
p.line(AAPL['Date'], AAPL['Close'], color='navy', alpha=0.5)
show(p)
And the image:
From what it seems it's automatically turned off, and the x-axis updates properly as you zoom in, but it would be great to include minor ticks for visualization purpose.
As of Bokeh 0.10, the BokehJS DatetimeTicker sets num_minor_ticks to zero on the internal tickers that it uses:
https://github.com/bokeh/bokeh/blob/master/bokehjs/src/coffee/ticking/datetime_ticker.coffee#L23
There is currently no simple way exposed to override this (You could write some JavaScript to reach in directly, but that would be a pain). I am not sure if this state of affairs is due to some inherent problem with minor ticks and datatime ranges, or if this was merely an oversight. Please make a new issue on the Bokeh GH issue tracker so it can be investigated:
https://github.com/bokeh/bokeh/issues
As a frequent user of pandas, I often want to plot my data.
Using the df.plot() is very convenient, and I like the layout it gives me.
I often have the problem that when I show the generated graph to someone else, they like it, but want some tiny changes.
This often digresses into me trying to recreate the exact graph in matplotlib, which turns into a couple of hundred rows of code and it still does not work quite the same way as the df.plot()
Is there a way to get the settings for the default plotting behaviour from pandas and just ad something to the plot?
Example:
df = pd.DataFrame([1,2,3,6],index=[15,16,17,18], columns=['values'])
df.plot(kind='bar')
This little piece of code makes this pretty graph:
Trying to recreate this with matplotlib turns into a few hours of digging through documentation and still not comming up with quite the right solution.
Not to mention how many lines of configuration code it is.
import matplotlib.pyplot as plt
import matplotlib.ticker as plticker
import matplotlib.patches as mpatches
fig, ax1 = plt.subplots()
ax1.bar(df.index, df['values'], 0.4, align='center')
loc = plticker.MultipleLocator(base=1.0)
ax1.xaxis.set_major_locator(loc)
ax1.xaxis.set_ticklabels(["","15", "16", "17", "18"])
plt.show()
TLDR;
How can I easily copy the behaviour of df.plot() and extend it, without having to recreate everything manually?
I'm asking this question because I can't solve one problem in Python/Django (actually in pure Python it's ok) which leads to RuntimeError: tcl_asyncdelete async handler deleted by the wrong thread. This is somehow related to the way how I render matplotlib plots in Django. The way I do it is:
...
import matplotlib.pyplot as plt
...
fig = plt.figure()
...
plt.close()
I extremely minimized my code. But the catch is - even if I have just one line of code:
fig = plt.figure()
I see this RuntimeError happening. I hope I could solve the problem, If I knew the correct way of closing/cleaning/destroying plots in Python/Django.
By default matplotlib uses TK gui toolkit, when you're rendering an image without using the toolkit (i.e. into a file or a string), matplotlib still instantiates a window that doesn't get displayed, causing all kinds of problems. In order to avoid that, you should use an Agg backend. It can be activated like so --
import matplotlib
matplotlib.use('Agg')
from matplotlib import pyplot
For more information please refer to matplotlib documentation -- http://matplotlib.org/faq/howto_faq.html#matplotlib-in-a-web-application-server
The above (accepted) answer is a solution in a terminal environment. If you debug in an IDE, you still might wanna use 'TkAgg' for displaying data. In order to prevent this issue, apply these two simple rules:
everytime you display your data, initiate a new fig = plt.figure()
don't close old figures manually (e.g. when using a debug mode)
Example code:
import matplotlib
matplotlib.use('TkAgg')
from matplotlib import pyplot as plt
fig = plt.figure()
plt.plot(data[:,:,:3])
plt.show()
This proves to be the a good intermediate solution under MacOS and PyCharm IDE.
If you don't need to show plots while debugging, the following works:
import matplotlib
matplotlib.use('Agg')
from matplotlib import pyplot as plt
However, if you would like to plot while debugging, you need to do 3 steps:
1.Keep backend to 'TKAgg' as follows:
import matplotlib
matplotlib.use('TKAgg')
from matplot.lib import pyplot as plt
or simply
import matplotlib.pyplot as plt
2.As Fábio also mentioned, you need to add fig(no. #i)=plt.figure(no.#i) for each figure #i. As the following example for plot no.#1, add:
fig1 = plt.figure(1)
plt.plot(yourX,yourY)
plt.show()
3.Add breakpoints. You need to add two breakpoints at least, one somewhere at the beginning of your codes (before the first plot), and the other breakpoint at a point where you would like all plots (before to the second breakpoint) are plotted. All figures are plotted and you even don't need to close any figure manually.
For me, this happened due to parallel access to data by both Matplotlib and by Tensorboard, after Tensorboard's server was running for a week straight.
Rebotting tensorboard tensorboard --logdir . --samples_per_plugin images=100 solved this for me.
I encountered this problem when plotting graphs live with matplotlib in my tkinter application.
The easiest solution I found, was to always delete subplots. I found you didn't need to instantiate a new figure, you only needed to delete the old subplot (using del subplot), then remake it.
Before plotting a new graph, make sure to delete the old subplot.
Example:
f = Figure(figsize=(5,5), dpi=100)
a = f.add_subplot(111)
(For Loop code that updates graph every 5 seconds):
del a #delete subplot
a = f.add_subplot(111) #redefine subplot
Finding this simple solution to fix this "async handler bug" was excruciatingly painful, I hope this helps someone else :)
programming noob here. I'm trying to use a matplotlib widget in a PyQt4 GUI. The widget is similar to matplotlib's example for qt.
At some point the user needs to click on the plot, which I thought something like ginput() would handle. However, this doesn't work because the figure doesn't have a manager (see below). Note that this is very similar to another question but it never got answered.
AttributeError: 'NoneType' object has no attribute 'manager'
Figure.show works only for figures managed by pyplot, normally created by pyplot.figure().
I'm assuming by "normally" there's a way around this.
Another simple script to demonstrate:
from __future__ import print_function
from matplotlib.figure import Figure
import numpy as np
import matplotlib.pyplot as plt
x = np.arange(0, 5, 0.1)
y = np.sin(x)
# figure creation by plt (also given a manager, although not explicitly)
plt.figure()
plt.plot(x,y)
coords = plt.ginput() # click on the axes somewhere; this works
print(coords)
# figure creation w/o plt
manualfig = Figure()
manualaxes = manualfig.add_subplot(111)
manualaxes.plot(x,y)
manualfig.show() # will fail because of no manager, yet shown as a method
manualcoords = manualfig.ginput() # comment out above and this fails too
print(manualcoords)
As popular as pyplot is (I can't hardly find an answer without it), it doesn't seem to play nice when working with a GUI. I thought pyplot was simply a wrapper for the OO framework but I guess I'm just a noob.
My question then is this:
Is there some way to attach pyplot to an instance of matplotlib.figure.Figure?
Is there an easy way to attach a manager to a Figure? I found new_figure_manager() in matplotlib.backends.backend_qt4agg, but couldn't get it to work, even if it is the right solution.
Many thanks,
James
pyplot is just a wrapper for the OO interface, but it does a lot of work for you read the example you link to again carefully, the
FigureCanvas.__init__(self, fig)
line is very important as that is what tells the figure what canvas to use. The Figure object is just a collection of Axes objects (and a few Text objects), the canvas object is what knows how to turn Artist objects (ie matplotlib's internal representation of lines, text, points, etc) in to pretty colors. Also see something I wrote for another embedding example which does not sub-class FigureCanvas.
There is a PR to make this process easier, but it is stalled while we get 1.4 out the door.
also see: Which is the recommended way to plot: matplotlib or pylab?, How can I attach a pyplot function to a figure instance?