I'm using python pandas on a headless server to generate graphs which are subsequently served up on a web page. Because of the limitations, I can't use the well-written .plot() functionality in pandas (which would automatically handle my formatting mess), and instead I must create the graph (.png file) in a way that doesn't create a new window.
Code below does everything I need, but I'm stumped on where/how to call autofmt_xdate. Run the code below and notice the x-axis date formatting mess. Any help is appreciated, and apologies for any formatting errors in posting this.
My goal is to have the x-axis dates rotated 30 degrees or so.
#! /usr/bin/python
from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
from matplotlib.figure import Figure
import numpy as np
import pandas as pd
rng = pd.date_range( '1/1/2011', periods=20, )
ts = pd.Series(np.random.randn(len(rng)), index=rng)
fig = Figure()
canvas = FigureCanvas(fig)
ax = fig.add_subplot(111)
ax.plot_date(ts.index, ts, '-')
#ax.autofmt_xdate(rotation=30) # this doesn't work. Help!
canvas.print_png('test.png')
Related
This question already has an answer here:
How to save candlestick chart in matplotlib finance
(1 answer)
Closed 1 year ago.
I'm new to matplotlib. I'm struggling to customise elements of my plot within the first .plot call. For example, ylabel works but xlabel doesn't. I was hoping I could separate the savefig command so that I could add/modify elements of the plot between the first .plot call and the savefig call (because all the examples I see online seem to create the plot and then modify elements separately, i.e. the line fplt.xlabel("Blah")
I notice that a lot of plot examples I found online (for line graphs and such) provide all x and y values separately, but I like the plot technique I've used as it automatically uses high, low, etc. to create candles.
So why does this code work:
fplt.plot(
dft,
type="candle",
style='charles',
addplot=extraPlot2,
ylabel=stock,
# xlabel="Blah", <= removed as doesn't work
figratio=(10, 6), volume=True,
savefig=dict(
fname=folder2,
bbox_inches="tight"
)
)
But this code doesn't (even with the hashes added):
fplt.plot(
dft,
type="candle",
style='charles',
addplot=extraPlot2,
ylabel=stock,
# xlabel="Blah", <= removed as doesn't work
figratio=(10, 6), volume=True,
)
# fplt.xlabel("Blah") <= would like to do this if I can get savefig to work
# fplt.xticks(rotation=45) <= i'd also like to do stuff like this
fplt.savefig(folder2)
I've tried making fplt.plot a variable and targeting that but with no luck.
Apologies for any poor terminology, I am very new to this.
EDIT: Imports added below for reference. And I realise why xlabel wasn't working now, as I see I was importing it.
import datetime as dt
from matplotlib.pyplot import bar, xlabel
from numpy import False_, NaN
import pandas as pd
from pandas_datareader import data as pdr
import yfinance as yf
from tkinter import EXCEPTION, Tk
from tkinter.filedialog import askopenfilename
import os
from pandas import ExcelWriter
import mplfinance as fplt
from pathlib import Path
You can import the Matplotlib pyplot module and use the gcf() ("get current figure") function to return a Figure object. It is the Figure object that has the savefig() method. E.g.,
from matplotlib import pyplot as plot
# your code here
fig = plt.gcf() # gcf is "get current figure"
fig.savefig(folder2)
Looking at this mplfinance issue it also looks like you can return the figure object with:
fig, axlist = fplt.plot(..., returnfig=True)
# save figure
fig.savefig(folder2)
Currently, I am attempting to follow along with a Sentdex YouTube tutorial video (https://www.youtube.com/watchv=cExOVprMlQg&list=PLQVvvaa0QuDe6ZBtkCNWNUbdaBo2vA4RO), however I am running into some difficulties with plt.show(). I have written this script nearly verbatim as detailed in this video and I have turned to StackOverflow to update any syntax, yet I have not been able to actually view this graph. Nothing comes up when I run the script, the shell just spits out '>>'. I have changed backends, unistalled, upgraded and reinstalled matplotlib. I've also tried this script on the exact version of Python seen in this video as well as 3.6.1 and a few others on OS X and Windows 10 via Parallels - still running into the same issue.
Here is my code thus far:
import matplotlib
import matplotlib.pyplot as plt
import matplotlib.ticker as mticker
import matplotlib.dates as mdates
import numpy as np
import pylab
def graphRawFX():
date, bid, ask = np.loadtext('GBPUSD1d.txt', unpack=True,
delimiter='-',
converters={0: mdates.strpdate2numb('%Y%m%d%H%M%S')})
fig = plt.figure(figsize=(10,7))
ax1 = plt.subplot2grid((40,40), (0), rowspan=40, colspan=40)
ax1.plot(date, bid)
ax1.plot(date, ask)
ax1.xaxis.set_major_formatter(mdate.DateFormatter('%Y-%m-%d %H:#M:#S'))
for label in ax1.axis,get_xticklabels():
label.set_rotation(45)
ply.gca().get_yaxis().get_major_formatter().set_useOffset(False)
plt.grid(True)
plt.show()
pylab.show()
Any thoughts on a solution?
You defined a function, which plots. But you never call the function! Your script is empty from python's perspective.
Add graphRawFX() at the end, without any indentation to actually call the function.
If this code is by any means incomplete and not your issue, check your install and clean up the code. The whole import pylab thing looks unwanted. Also ply does not exist and so on. Start with the basics, the official examples and the docs, not with some yt-video which uses tons of (advanced) stuff.
I have it working (mac OS). Just try to copy paste to see if there's some typing problem. (it was working without "import pylab" and the "pylab.show()" I have just put it to have the same code you have.
import matplotlib
import matplotlib.pyplot as plt
import matplotlib.ticker as mticher
import matplotlib.dates as mdates
import numpy as np
import pylab
def graphRawFX():
date,bid,ask = np.loadtxt('GBPUSD1d.txt', unpack=True, delimiter=',',converters={0:mdates.strpdate2num('%Y%m%d%H%M%S')})
fig = plt.figure(figsize=(10,7))
ax1 = plt.subplot2grid((40,40), (0,0), rowspan=40, colspan=40)
ax1.plot(date,bid)
ax1.plot(date,ask)
plt.gca().get_yaxis().get_major_formatter().set_useOffset(False)
ax1.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d %H:%M:%S'))
for label in ax1.xaxis.get_ticklabels() :
label.set_rotation(45)
ax1_2=ax1.twinx()
ax1_2.fill_between(date,0, (ask-bid),facecolor='g',alpha=.3)
plt.subplots_adjust(bottom=.23)
plt.grid(True)
plt.show()
pylab.show()
graphRawFX()
I followed the setting from here to make matplotlib/seaborn available to display in Zeppelin. However, with the following code:
%python
import seaborn as sns
import matplotlib
import numpy as np
matplotlib.use('Agg')
import matplotlib.pyplot as plt
plt.rcdefaults()
import StringIO
def show(p):
img = StringIO.StringIO()
p.savefig(img, format='svg')
img.seek(0)
print "%html <div style='width:600px'>" + img.buf + "</div>"
""" Prepare your plot here ... """
# Use the custom show function instead of plt.show()
x = np.random.randn(100)
ax = sns.distplot(x)
show(sns.plt)
It is strange that the displayed figure show the desired lightblue color the first time I run the code but will display different colors if I execute the same piece of code. Is there a way to force seaborn to keep constant color being displayed? Thanks.
It's not entirely clear what is meant by "running a second time".
However you may try to actually close the figure before running it again. E.g.
plt.close("all")
in order to make sure, a new figure is created which should have the same default color every time.
I've been using matplotlib for five months now on a daily basis, and I still find creation of new figures confusing.
Usually I create a figure with 2x2 subplots using, for example, somthing like:
import matplotlib.pyplot as plt
import itertools as it
fig,axes = plt.subplots(2,2)
axit = (ax for ax in it.chain(*axes))
for each of four data series I want to plot:
ax = next(axit)
ax.plot(...)
The question I have now is: how can operate completely independently of pyplot, ie, how can I create a figure, populate it with plots, make style changes, and only tell that figure to appear at the exact moment I want it to appear. Here is what I am having trouble with:
import matplotlib as mpl
gs = gridspec.GridSpec(2,2)
fig = mpl.figure.Figure()
ax1 = fig.add_subplot(gs[0])
ax1.plot([1,2,3])
ax2 = fig.add_subplot(gs[1])
ax2.plot([3,2,1])
After running the above, the only thing that comes to mind would be to use:
plt.draw()
But this does not work. What is missing to make the figure with the plots appear? Also, is
fig = mpl.figure.Figure()
all I have to do to create the figure without pyplot?
This works for me without matplotlib.pyplot
import sys
from PyQt5 import QtWidgets
from matplotlib.backends.backend_qt5agg import (
FigureCanvasQTAgg as FigureCanvas)
from matplotlib.figure import Figure
import numpy as np
fig=Figure()
canvas=FigureCanvas(fig)
ax=canvas.figure.add_subplot(111)
x=np.arange(-5,5,0.1)
y=np.sin(x)
ax.plot(x,y)
canvas.show()
app=QtWidgets.QApplication(sys.argv)
app.exec()
You could attach a suitable backend to your figure manually and then show it:
from matplotlib.backends import backend_qt4agg # e.g.
backend_qt4agg.new_figure_manager_given_figure(1, fig)
fig.show()
... but why not use pyplot?
New to matplotlib and trying to explore existing data by iterating through a DataFrame via animation, but it seems very slow, can anyone see what I'm doing wrong or suggest improvements, have tried playing with frame speed but has little effect so I think its my code, would like to view this 2000 row object in 15 sec give or take. box is 8gb linex so should be fine, using ipython pop out figure to plot.
from pandas import *
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import animation
coef_mean = DataFrame(np.random.rand(2000,50))
def animate(f_frame):
plt.cla()
plt.plot(coef_mean.columns.values, coef_mean.ix[f_frame])
plt.ylim(f_coef_min,f_coef_max)
fig = plt.figure(figsize=(9,5))
f_coef_min, f_coef_max = coef_mean.min().min()-.02, coef_mean.max().max()+.02
anim = animation.FuncAnimation(fig, animate, frames=150)
plt.show()
any ideas out there what I have done wrong ? many thanks, LW
also to get the popout figure try using
%matplotlib qt
You don't need to replot inside the animation function. Instead, you should just update the data of the plot. In your case something like this should work:
fig, ax = plt.subplots()
custom_plot, = ax.plot(coef_mean.columns.values, coef_mean.ix[0])
ax.set_ylim(f_coef_min,f_coef_max)
def animate(f_frame):
custom_plot.set_ydata(coef_mean.ix[f_frame])
return custom_plot,
Look at some animation examples for more information. E.g:
http://matplotlib.org/examples/animation/simple_anim.html