I am using BackTrader for backtesting (using python3 in Jupiter Notebook on a Mac), and have used the following example from their documentation found at https://www.backtrader.com/docu/plotting/plotting.html:
import backtrader as bt
class Ind(bt.Strategy):
def __init__(self):
self.sma = bt.indicators.SimpleMovingAverage(self.data)
datapath = 'CSV file on my computer.txt'
data = bt.feeds.BacktraderCSVData(dataname = datapath)
cerebro = bt.Cerebro()
cerebro.adddata(data)
cerebro.addstrategy(Ind)
cerebro.run()
cerebro.plot()
When I plot a graph using BackTrader's cerebro.plot() function, it works fine the first time (see picture 1). First time plot
However, when I re-run the cell again (to tweak inputs), it disappears and is just left with the figure size output at the bottom (see picture 2). Output after re-running cell
It still doesn't work if I copy and paste the code in a new cell below and run it. I am still just left with the figure size output at the bottom.
This is very frustrating as every time I want to reproduce one of their plots, I am having to restart Jupiter notebook to do it.
Thanks in advance!
I've encountered the same problem, I believe it it related to backtrader's interactions with matplotlib. I was able to fix it by including the line
%matplotlib inline
at the very top of my notebook (being right at the very top seems to be important, as noted here). I did NOT need to include statements like import matplotlib.
This generates a system warning message each time a plot is generated, these can be suppressed using
import warnings
warnings.filterwarnings('ignore')
as noted in this question.
Minimal failing repro of the op's issue:
In [1]:
import backtrader as bt
import datetime
if __name__ == '__main__':
cerebro = bt.Cerebro()
data = bt.feeds.YahooFinanceData(
dataname='AAPL',
fromdate=datetime.datetime(2000, 1, 1),
todate=datetime.datetime(2000, 12, 31),
reverse=False)
cerebro.adddata(data)
cerebro.run()
cerebro.plot(style='bar')
In [2]:
cerebro.plot(style='bar')
Fixed version of minimal failing repro:
In [1]:
%matplotlib inline
import warnings
warnings.filterwarnings('ignore')
import backtrader as bt
import datetime
if __name__ == '__main__':
cerebro = bt.Cerebro()
data = bt.feeds.YahooFinanceData(
dataname='AAPL',
fromdate=datetime.datetime(2000, 1, 1),
todate=datetime.datetime(2000, 12, 31),
reverse=False)
cerebro.adddata(data)
cerebro.run()
cerebro.plot(style='bar')
In [2]:
cerebro.plot(style='bar')
Related
When I use the examples to make a calendar heatmap and run my Python script from the terminal, I see my computer briefly open then close IDLE and the script appears to be finished running.
import numpy as np; np.random.seed(sum(map(ord, 'calplot')))
import pandas as pd
import calplot
import calmap
all_days = pd.date_range('1/1/2019', periods=730, freq='D')
days = np.random.choice(all_days, 500)
events = pd.Series(np.random.randn(len(days)), index=days)
calplot.calplot(events, cmap='YlGn', colorbar=False) # if I use this or the line above or both the same thing happens
calmap.yearplot(events, year=2019) # if I use this or the line above or both the same thing happens
I have tried installing all of the referenced libraries used by calplot and calmap, and no luck still. I have confirmed I can plot using Matplotlib, so it isn't a graphics issue
I am generating a map inside Google Colab using the Folium python library and would like to show a progress bar as the code is working on spitting out a map rendering.
I'm fairly new to programming, but I gather that tqdm can generate a status bar over an iterable. I don't necessarily have an iterable built into my code, but I'm wondering how to 'wrap' my code in a tqdm function to show a status bar as I wait for the various !pip install, import, and folium functions to run. Unfortunately, Colab forces me to run the !pip install statements each time in order to work properly.
Here is my code for generating a fairly simple map, although the status bar doesn't behave as expected:
for i in tqdm(range(1), desc = 'Generating Map'):
!pip install geopandas &> /dev/null
!pip install branca &> /dev/null
import folium
from folium.plugins import HeatMap
from folium.features import GeoJsonTooltip
import geopandas as gpd
import pandas as pd
import os
from branca.element import Figure
import glob
from google.colab import drive
m=folium.Map(location=[40.43912857098136, -79.94770150049476],tiles=None)
folium.TileLayer(
tiles = 'https://mt1.google.com/vt/lyrs=m&x={x}&y={y}&z={z}',
attr = 'Google',
name = 'Google Maps',
overlay = False,
control = True,
zoom_start = 12,
min_zoom = 8,
max_zoom = 20,
opacity = 1
).add_to(m)
m
I'm installing geopandas and branca to use when my map becomes more complex. This is a fairly slimmed-down version of my entire code.
Problem is, the status bar doesn't begin to tick forward until the very last section of the code, when it zooms ahead to 100%. It just blinks for the first few seconds when I run this. I'd like the status bar to begin immediately upon running the very first !pip install command.
This particular chunk of code only takes a few seconds to run, but later I'll want to add a choropleth map and other shapefile layers to the map that will undoubtedly slow down the time it takes to execute. Hence, a progress bar to show the user a status would be quite helpful.
I'm using pycharm to run some code using Seaborn. I'm very new to python and am just trying to learn the ropes so I'm following a tutorial online. I've imported the necessary libraries and have run the below code
import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
# import the data saved as a csv
df = pd.read_csv('summer-products-with-rating-and-performance_2020-08.csv')
df["has_urgency_banner"] = df["has_urgency_banner"].fillna(0)
df["discount"] = (df["retail_price"] -
df["price"])/df["retail_price"]
df["rating_five_percent"] = df["rating_five_count"]/df["rating_count"]
df["rating_four_percent"] = df["rating_four_count"]/df["rating_count"]
df["rating_three_percent"] = df["rating_three_count"]/df["rating_count"]
df["rating_two_percent"] = df["rating_two_count"]/df["rating_count"]
df["rating_one_percent"] = df["rating_one_count"]/df["rating_count"]
ratings = [
"rating_five_percent",
"rating_four_percent",
"rating_three_percent",
"rating_two_percent",
"rating_one_percent"
]
for rating in ratings:
df[rating] = df[rating].apply(lambda x: x if x>= 0 and x<= 1 else 0)
# Distribution plot on price
sns.histplot(df['price'])
My output is as follows:
Process finished with exit code 0
so I know there are no errors in the code but I don't see any graphs anywhere as I'm supposed to.
Ive found a way around this by using this at the end
plt.show()
which opens a new tab and uses matplotlib to show me a similar graph.
However in the code I'm using to follow along, matplotlib is not imported or used (I understand that seaborn has built in Matplotlib functionality) as in the plt.show statement is not used but the a visual graph is still achieved.
I've also used print which gives me the following
AxesSubplot(0.125,0.11;0.775x0.77)
Last point to mention is that the code im following along with uses the following
import seaborn as sns
# Distribution plot on price
sns.distplot(df['price'])
but distplot has now depreciated and I've now used histplot because I think that's the best alternative vs using displot, If that's incorrect please let me know.
I feel there is a simple solution as to why I'm not seeing a graph but I'm not sure if it's to do with pycharm or due to something within the code.
matplotlib is a dependency of seaborn. As such, importing matplotlib with import matplotlib.pyplot as plt and calling plt.show() does not add any overhead to your code.
While it is annoying that there is no sns.plt.show() at this time (see this similar question for discussion), I think this is the simplest solution to force plots to show when using PyCharm Community.
Importing matplotlib in this way will not affect how your exercises run as long as you use a namespace like plt.
Be aware the 'data' must be pandas DataFrame object, not: <class 'pandas.core.series.Series'>
I using this, work finely:
# Distribution plot on price
sns.histplot(df[['price']])
plt.show()
I'm trying to print a graph from a Python script on AWS Linux over SSH/Xming on my Windows machine. Everything works nicely if I use a blocking plt.show() - I can't, however, show the graph correctly when running in a loop without blocking. My sample code is:
import matplotlib
matplotlib.use('Agg')
import seaborn as sns
import matplotlib.pyplot as plt
import time
import pandas as pd
import numpy as np
df = pd.DataFrame(np.random.randn(100, 4), columns=list('ABCD'))
while True:
heatmap = sns.heatmap(df)
plt.show(block=False)
time.sleep(10)
This setup (without the first two lines) works smoothly in Windows with Anaconda and IPyhon - I get an alternating plot and sleep. I'm getting no output this way with Linux though.
I am using the anaconda distribution of ipython/Qt console. I want to plot things inline so I type the following from the ipython console:
%pylab inline
Next I type the tutorial at (http://pandas.pydata.org/pandas-docs/dev/visualization.html) into ipython...
import matplotlib.pyplot as plt
import pandas as pd
ts = pd.Series(randn(1000), index = pd.date_range('1/1/2000', periods=1000))
ts = ts.cumsum()
ts.plot()
... and this is all that i get back:
<matplotlib.axes.AxesSubplot at 0x109253410>
But there is no plot. What could be wrong? Is there another command that I need to supply? The tutorial suggests that that is all that I need to type.
Plots are not displayed until you run
plt.show()
There could be 2 ways to approach this problem:
1) Either invoke the inline/osx/qt/gtk/gtk3/tk backend. Depends on the ipython console that you have been using. So, simply do:
%matplotlib inline #Here the inline backend is invoked, which removes the necessity of calling show after each plot.
or for ipython/qt console, do:
%matplotlib qt #This one works for me, thus, depends on the ipython console you use.
#
2) Or, do the traditional way as aforementioned (already answered above on this page):
plt.show() #However, you will have to call this show function each time.