Callback function not using the source file to update the graph - pandas

Im using a csv file as my data source. I want the graph to update based on the radio button selection i make, please find my source code below.
import pandas as pd
import numpy as np
import plotly.graph_objs as go
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input,Output
df = pd.read_csv('population2.csv')
fst_yvalues = df['PopEstimate2010']/1000000
scd_yvalues = df['PopEstimate2011']/1000000
trd_yvalues = df['PopEstimate2012']/1000000
app = dash.Dash()
app.layout = html.Div(children=[
html.H1('My first Interactive Graph'),
html.Div(dcc.RadioItems(id='radio_items',
options=[{'label':'PopEstimate2010','value':'pop2010'},
{'label':'PopEstimate2011','value': 'pop2011'},
{'label':'PopEstimate2011' ,'value':'pop2012'}],
value='pop2010')),
html.Br(),
html.Div(children=[
dcc.Graph(id='int_bar')])])
#app.callback(Output('int_bar','figure'),[Input('radio_items','value')])
def bar_chart(value):
trace = []`
if value == 'pop2010':
trarce = [go.Bar(x=df['Name'],y=fst_yvalues)]
elif value == 'pop2011':
trarce = [go.Bar(x=df['Name'],y=scd_yvalues)]
else:
trarce = [go.Bar(x=df['Name'],y=trd_yvalues)]
layout = go.Layout(title='MY FIRST GRAPH',
xaxis=dict(title='MY X-AXIS'),
yaxis=dict(title='MY Y-AXIS'),hovermode='closest')
figure = go.Figure(data=trace,layout=layout)enter code here
return figure
if __name__ == '__main__':
app.run_server(debug=True)
When i try to run this, it only gives me the layout but not the actual graph.

Below is the approach i have taken to get this to work :
#app.callback(Output('int_bar','figure'),[Input('radio_items','value')])
def make_bar_chart(value):
if value == 'pop2010':
figure = {'data': [go.Bar(x=df['Name'],y=fst_yvalues)],
'layout': go.Layout(title='MY FIRST GRAPH',
xaxis=dict(title='MY X-AXIS'),
yaxis=dict(title='MY Y-AXIS'),hovermode='closest')
}
...
...
return figure
if __name__ == '__main__':
app.run_server(debug=True)

Related

choropleth plotly map displaying a white background

I am trying to create a choropleth map of the uk using plotly, but every time I try, it outputs an empty page, or the json doesn't match with the dataframe.this is where i obtained the url for the dataframe Here's my code so far:
import pandas as pd
from urllib.request import urlopen
import json
with urlopen('https://raw.githubusercontent.com/deldersveld/topojson/master/countries/united-kingdom/uk-counties.json') as response:
geojson = json.load(response)
url3 = 'https://api.coronavirus.data.gov.uk/v2/data?areaType=utla&metric=cumCasesBySpecimenDate&metric=cumPeopleVaccinatedFirstDoseByVaccinationDate&metric=cumPeopleVaccinatedSecondDoseByVaccinationDate&metric=newCasesBySpecimenDate&metric=cumPeopleVaccinatedThirdInjectionByVaccinationDate&format=csv'
df = pd.read_csv(url3)
df_new=df.replace("areaName", "NAME_2")
from plotly import graph_objects as go
fig = go.Figure(
go.Choroplethmapbox(
geojson=geojson,
featureidkey="properties.NAME_2",
locations=df["areaCode"],
z=df['cumCasesBySpecimenDate'],
zauto=True,
colorscale='Reds',
showscale=True,
)
)
fig.show()
a few things to fix this up:
uk-counties.json is in topojson format, plotly needs a geojson. can fix with the topojson module, for example (or geopandas)
no need to replace "areaName", you want this: locations=df["areaName"]
you need to specify a marker_style. centering and zooming help as well
for good result you need to use only one day's worth of data per choropleth, hence the df = df[df['date'] == '2022-11-23']
the covid data and the topojson don't match up well by districts, so there are gaps in the map
code:
"""
https://stackoverflow.com/questions/71828342/choropleth-plotly-map-displaying-a-white-background
"""
from urllib.request import urlretrieve
import json
from io import StringIO
from plotly import graph_objects as go
import pandas as pd
import topojson as tp
URL_JSON = 'https://raw.githubusercontent.com/deldersveld/topojson/master/countries/united-kingdom/uk-counties.json'
URL_DATA = 'https://api.coronavirus.data.gov.uk/v2/data?areaType=utla&metric=cumCasesBySpecimenDate&metric=cumPeopleVaccinatedFirstDoseByVaccinationDate&metric=cumPeopleVaccinatedSecondDoseByVaccinationDate&metric=newCasesBySpecimenDate&metric=cumPeopleVaccinatedThirdInjectionByVaccinationDate&format=csv'
CSV_DATA = 'uk_covid.csv'
TOPO_DATA = 'topojson.json'
GEO_DATA = 'geojson.json'
def download():
urlretrieve(URL_JSON, TOPO_DATA)
with open(TOPO_DATA, 'r') as data:
topoJSON = json.load(StringIO(data.read()))
topo = tp.Topology(topoJSON, object_name='GBR_adm2')
# convert to geojson, store in GEO_DATA
topo.to_geojson(GEO_DATA)
df = pd.read_csv(URL_DATA)
df.to_csv(CSV_DATA)
def make_map():
df = pd.read_csv(CSV_DATA)
with open(GEO_DATA, 'r') as data:
geojson = json.load(StringIO(data.read()))
# one day at a time
df = df[df['date'] == '2022-11-23']
fig = go.Figure(
go.Choroplethmapbox(
geojson=geojson,
featureidkey="properties.NAME_2",
locations=df["areaName"], # <=== not areaCode
z=df['cumCasesBySpecimenDate'],
zauto=True,
colorscale='Reds',
showscale=True
)
)
# need a mapbox_style
fig.update_layout(mapbox_style='carto-positron',
mapbox_zoom=5,
mapbox_center_lon=-2.057852,
mapbox_center_lat=53.404854,
height=700,
width=700)
fig.show()
if 0: # only needed once
download()
make_map()

Conditions True and false and I get None value

This is my data
!pip install yfinance
import yfinance as yf
from pandas_datareader import data
import matplotlib.pyplot as plt
import pandas as pd
import datetime as dt
import urllib.request, json
import os
import numpy as np
data=yf.download('AAPL', period='max', interval='5d' )
# find the log return which is equal to log(1+ri)
data['LogReturn'] = np.log(data['Close']).diff()
data['LogReturn'] = data['LogReturn'].shift(-1)
Fast=10
Slow=30
data['SlowSMA'] = data['Close'].rolling(Slow).mean()
data['FastSMA'] = data['Close'].rolling(Fast).mean()
data['Signal']=np.where(data['FastSMA'] >= data['SlowSMA'], 1, 0)
data['PrevSignal']=data['Signal'].shift(1)
data['Buy'] = (data['PrevSignal'] == 0) & (data['Signal'] == 1)
data['Sell'] = (data['PrevSignal'] == 1) & (data['Signal'] == 0)
def assign_is_invested(row): ## we will look at each row
global is_invested # we can change it outside the function
if is_invested and row['Sell']:
is_invested=False
if not is_invested and row['Buy']:
is_invested=True
return is_invested
data['IsInvested'] = data.apply(assign_is_invested, axis=1)
When I run the above function to get the IsInvested column None and I am expecting True or False. Why is that?
I believe that the problem is with the indentation of the return.
is_invested= False # we are not invested yet no money
def assign_is_invested(row): ## we will look at each row
global is_invested # we can change it outside the function
if is_invested and row['Sell']:
is_invested=False
if not is_invested and row['Buy']:
is_invested=True
return is_invested
data['IsInvested'] = data.apply(assign_is_invested, axis=1)
The function was only returning the is_invested variable if the data matched the criteria in the second IF statement.

Syntax error in plt.gcf(). Used on geographical climate dataset

I am attempting to plot a downloaded .nc file containing geographical climate data.
In the last step, I get a syntax error for the following line: plt.gcf().set_size_inches(20,10). I cannot seem to locate the error.
After successfully downloading the file, this is the code I used to plot the data:
import numpy as np
import xarray # used for reading the data.
import matplotlib.pyplot as plt # used to plot the data.
import ipywidgets as widgets # For ease in selecting variables.
import cartopy.crs as ccrs # Used to georeference data.
filelist_arr = [save_dir + os.path.basename(file) for file in filelist]
selected_file = widgets.Dropdown(options=filelist_arr, description='data file')
display(selected_file)
# Now to load in the data to xarray
ds = xarray.open_dataset(selected_file.value)
# Helper methods# Define function to get standard dimensions
def get_time(dataset):
for _,cur_coord in dataset.coords.items:
if cur_coord.attrs['standard_name'] == 'time':
return cur_coord
def get_lat(dataset):
for _,cur_coord in dataset.coords.items:
if cur_coord.attrs['standard_name'] == 'longitude':
return cur_coord
def get_lon(dataset):
for _,cur_coord in dataset.coords.items:
if cur_coord.attrs['standard_name'] == 'latitude':
return cur_coord
def get_primary(dataset):
primary_variables = {}
coords = dataset.coords.keys()
highest_dims = 0
for cur_key,cur_var in dataset.variables.items():
if cur_key not in coords:
primary_variables[cur_key] = cur_var
return primary_variables
var = widgets.Dropdown(
options=get_primary(ds).keys(),
description='Variable')
display(var)
So far so good. Now, in the final block, I get a syntax error in line 3.
var = widgets.Dropdown(
proj = ccrs.Mercator()
plt.gcf().set_size_inches(20,10)
ax = plt.axes(projection=proj)
data_slice = ds[var.value].isel(time=10)
data_slice.plot.contourf(ax=ax, transform=ccrs.PlateCarree())
ax.set_global()
ax.coastlines()
This is the error:
File "<ipython-input-80-8848cc5cc689>", line 3
plt.gcf().set_size_inches(20,10)
^
SyntaxError: invalid syntax
Can anybody explain what I am doing wrong?
I think you got a little bit confused by trying to wrap the code inside the widgets.Dropdown() code.
Perhaps it's a good idea to write the code without widgets first, and then add them later if your code works. Can you try the following code, and see which errors appears then:
import numpy as np
import xarray
import matplotlib.pyplot as plt
import ipywidgets as widgets
import cartopy.crs as ccrs
# Load data into memory
filelist_arr = [save_dir + os.path.basename(file) for file in filelist]
selected_file = widgets.Dropdown(options=filelist_arr, description='data file')
# Create xarray
ds = xarray.open_dataset(selected_file.value)
# Helper methods
def get_time(dataset):
for _,cur_coord in dataset.coords.items:
if cur_coord.attrs['standard_name'] == 'time':
return cur_coord
def get_lat(dataset):
for _,cur_coord in dataset.coords.items:
if cur_coord.attrs['standard_name'] == 'longitude':
return cur_coord
def get_lon(dataset):
for _,cur_coord in dataset.coords.items:
if cur_coord.attrs['standard_name'] == 'latitude':
return cur_coord
def get_primary(dataset):
primary_variables = {}
coords = dataset.coords.keys()
highest_dims = 0
for cur_key,cur_var in dataset.variables.items():
if cur_key not in coords:
primary_variables[cur_key] = cur_var
return primary_variables
# Ask user to select dataset
var = widgets.Dropdown(
options=get_primary(ds).keys(),
description='Variable')
display(var)
# Initialize new figure and specify figure size
plt.figure(num=None, figsize=(20, 10))
# Create Mercator projection with dateline in the middle
ax = plt.axes(projection=ccrs.Mercator(central_longitude=180))
# Draw coastlines
ax.coastlines()
# Select the appropriate data and plot to the axes
data_slice = ds[var.value].isel(time=10)
data_slice.plot.contourf(ax=ax, transform=ccrs.PlateCarree())
# Optional: set the map extent, for geographical coordinates
# ax.set_extent([90, 270, -40, 40], crs=ccrs.PlateCarree())
# Optional: add title
# plt.title('Geographical climate data at time = 10')
# Show the plot
plt.show()
If this still gives an error, please let me know in the comments below.

How to change ipython qtconsole input

I'm making a guide with pyqt and I'm including an ipython qtconsole widget.
try:
from qtconsole.rich_jupyter_widget import RichJupyterWidget as ipythonWidget
from qtconsole.inprocess import QtInProcessKernelManager
except:
from IPython.qt.console.rich_ipython_widget import RichIPythonWidget as ipythonWidget
from IPython.qt.inprocess import QtInProcessKernelManager
I want to modify the qtconsole input from my code but is not working. I've tried the set_next_input function but it doesn't work and I can't find another function I can use to acomplish what I want. Is even possible to achieve what I want? and if so, how can I do it?
Here is my code:
try:
from qtconsole.rich_jupyter_widget import RichJupyterWidget as ipythonWidget
from qtconsole.inprocess import QtInProcessKernelManager
except:
from IPython.qt.console.rich_ipython_widget import RichIPythonWidget as ipythonWidget
from IPython.qt.inprocess import QtInProcessKernelManager
import sys
from PyQt4 import QtGui
class sympyIpython(QtGui.QWidget):
def __init__(self):
super().__init__()
self.ipython = IpythonWidget()
v = QtGui.QVBoxLayout(self)
button = QtGui.QPushButton('append to input')
v.addWidget(self.ipython)
v.addWidget(button)
button.clicked.connect(self.symClicked)
def symClicked(self):
self.ipython.kernel.shell.set_next_input(' appended text')
class IpythonWidget(ipythonWidget):
def __init__(self):
super().__init__()
self.kernel_manager = QtInProcessKernelManager()
self.kernel_manager.start_kernel()
self.kernel = self.kernel_manager.kernel
self.kernel.gui = 'qt4'
self.kernel_client = self.kernel_manager.client()
self.kernel_client.start_channels()
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
m = sympyIpython()
m.show()
sys.exit(app.exec_())
Reposting as an answer:
To change the text at the prompt in the Qt console, set input_buffer on the widget object:
jupyter_widget.input_buffer = 'text'

matplotlib in gtk window with i18n (gettext) support

I am trying to show a matplotlib plot with axes labeled using gettext's _("label") construct. Trying to create a minimal example, I came up with the following python code. It runs fine through the NULLTranslations() like this:
python mpl_i18n_test.py
But when I switch to japanese, I get nothing but small squares in the plot -- though on the command-line, the translations look fine:
LANG=ja_JP.utf8 python mpl_i18n_test.py
Here is the file mpl_i18n_test.py
Note that this requires the mona-sazanami font installed, and the various python modules: pygtk, numpy, matplotlib, gettext and polib
So my question: Is there some trick to getting matplotlib play nicely with gettext? Am I missing something obvious here? Thank you.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import gtk
import numpy as np
import matplotlib as mpl
from matplotlib.figure import Figure
from matplotlib.backends.backend_gtkagg import \
FigureCanvasGTKAgg as FigureCanvas
from matplotlib.backends.backend_gtkagg import \
NavigationToolbar2GTKAgg as NavigationToolbar
import locale
import gettext
import polib
mpl.rcParams['font.family'] = 'mona-sazanami'
def append(po, msg):
occurances = []
for i,l in enumerate(open(__file__,'r')):
if "_('"+msg[0]+"')" in l:
occurances += [(__file__,str(i+1))]
entry = polib.POEntry(msgid=msg[0],
msgstr=msg[1],
occurrences=occurances)
print msg
print occurances
po.append(entry)
def generate_ja_mo_file():
po = polib.POFile()
msgs = [
(u'hello', u'こんにちは'),
(u'good-bye', u'さようなら'),
]
for msg in msgs:
append(po, msg)
po.save('mpl_i18n_test.po')
po.save_as_mofile('mpl_i18n_test.mo')
return 'mpl_i18n_test.mo'
def initialize():
'''prepare i18n/l10n'''
locale.setlocale(locale.LC_ALL, '')
loc,enc = locale.getlocale()
lang,country = loc.split('_')
l = lang.lower()
if l == 'ja':
filename = generate_ja_mo_file()
trans = gettext.GNUTranslations(open(filename, 'rb'))
else:
trans = gettext.NullTranslations()
trans.install()
if __name__ == '__main__':
initialize() # provides _() method for translations
win = gtk.Window(gtk.WINDOW_TOPLEVEL)
win.connect("destroy", lambda x: gtk.main_quit())
win.connect("delete_event", lambda x,y: False)
win.set_default_size(400,300)
win.set_title("Test of unicode in plot")
fig = Figure()
fig.subplots_adjust(bottom=.14)
ax = fig.add_subplot(1,1,1)
xx = np.linspace(0,10,100)
yy = xx*xx + np.random.normal(0,1,100)
ax.plot(xx,yy)
print 'hello --> ', _('hello')
print 'good-bye --> ', _('good-bye')
ax.set_title(u'こんにちは')
ax.set_xlabel(_('hello'))
ax.set_ylabel(_('good-bye'))
can = FigureCanvas(fig)
tbar = NavigationToolbar(can,None)
vbox = gtk.VBox()
vbox.pack_start(can, True, True, 0)
vbox.pack_start(tbar, False, False, 0)
win.add(vbox)
win.show_all()
gtk.main()
A solution I found was to merely specify unicode when the translation is "installed." It was a one-line change:
trans.install(unicode=True)
I will add that this is only needed in python 2.7, but not needed in python 3. Looks like python 2.6 and earlier still have issues with this