Preserving Axis annotation while interactively zooming in on a matplotlib basemap plot? - matplotlib-basemap

I'm creating a figure displaying the worldmap with some data on it (which is irrelevant here). Now I want to be able to zoom in on it using the Pan/Zoom-button or the Zoom-to-rectangle-button and then save the figure to a picture file once I'm done zooming in. The problem is that the axis annotations (and the lng-/lat-lines) are "hard-embedded" in the picture, which make them vanish when you zoom in.
Does anybody know how to get axis annotations that adapt to the zooming?
Here is a minimal working example (without any data):
import matplotlib as mpl
import matplotlib.pyplot as plt
from mpl_toolkits.basemap import Basemap
import numpy as np
fig = plt.figure(1, figsize=(12, 7))
m = Basemap(projection='merc',llcrnrlat=-80,urcrnrlat=80,\
llcrnrlon=-180,urcrnrlon=180,resolution='l') #,lat_ts=20
m.drawcoastlines(); m.fillcontinents(); m.drawcountries()
# draw parallels and meridians.
m.drawparallels(np.arange(-90.,91.,30.),labels=[True, False, False, False], color='White')
m.drawmeridians(np.arange(-180.,181.,60.), labels=[False, False, False, True], color='White')
plt.show()

Just in case someone ever stumbles upon my question, here is what I came up with as a rather quick work-around. :-)
My intended application was to zoom in and then save the figure. Now I do not do that interactively but by entering the "zoomed bounding box" in the code and dynamically creating lng/lat-ticks with the following function (which needs an import numpy as np beforehand):
def calculateBasemapTicks(minMaxList, nrOfParalles = 3, nrOfMeridians = 3):
"""
Attempts to calculate meaningful ranges for .basemap.drawparallels
and .drawmeridians. Enter a <minMaxList> in the form
[lng_min, lng_max, lat_min, lat_max].
Note that you might get rather ugly floats. I suggest using formatting
as in ".drawparallels(..., fmt='%.4f')" or similar.
"""
pAdjust = (minMaxList[3]-minMaxList[2])*0.1
mAdjust = (minMaxList[1]-minMaxList[0])*0.1
parallels = np.linspace(minMaxList[2]+pAdjust,minMaxList[3]-pAdjust,
nrOfParalles)
meridians = np.linspace(minMaxList[0]+mAdjust,minMaxList[1]-mAdjust,
nrOfMeridians)
return parallels, meridians

Related

How to Highlight any given path in pyvis network graph visualization?

I'm working on a project in which first i had to detect the shortest path in a huge network graph using a-star algorithm followed by visualizing the same graph using pyvis network. However in this pyvis network the path that I've calculated should be highlighted as shortest path.
eg: consider this code for game of thrones character network
from pyvis.network import Network
import pandas as pd
got_net = Network(height='750px', width='100%', bgcolor='#222222', font_color='white')
# set the physics layout of the network
got_net.barnes_hut()
got_data = pd.read_csv('https://www.macalester.edu/~abeverid/data/stormofswords.csv')
sources = got_data['Source']
targets = got_data['Target']
weights = got_data['Weight']
edge_data = zip(sources, targets, weights)
for e in edge_data:
src = e[0]
dst = e[1]
w = e[2]
got_net.add_node(src, src, title=src)
got_net.add_node(dst, dst, title=dst)
got_net.add_edge(src, dst, value=w)
neighbor_map = got_net.get_adj_list()
# add neighbor data to node hover data
for node in got_net.nodes:
node['title'] += ' Neighbors:<br>' + '<br>'.join(neighbor_map[node['id']])
node['value'] = len(neighbor_map[node['id']])
got_net.show('gameofthrones.html')
Now how do i highlight a specific path in this graph? i've gone through the documentation but there isn't anything similar
Here's an example using NetworkX to create the graph and gravis to visualize it. I had to use a different URL, hope it's the same data. I've used the weight as edge widths and colored some with large weights. Alternatively you can calculate a shortest path between two nodes of interest and then color that path or assign edge widths so it stands out.
Disclosure: I'm the author of gravis. I don't know if the same can be achieved with pyvis, but since I know that gravis supports the requirements well, I provided this solution and hope it's useful.
import gravis as gv
import networkx as nx
import pandas as pd
url = 'https://raw.githubusercontent.com/pupimvictor/NetworkOfThrones/master/stormofswords.csv'
got_data = pd.read_csv(url)
g = nx.Graph()
for i, (source, target, weight) in got_data.iterrows():
width = weight/10
g.add_edge(source, target, size=width, color='blue' if width > 3 else 'black')
gv.d3(g)
Edit: Here's the output if you use this code inside a Jupyter notebook. You can also use a regular Python interpreter and display the plot inside a browser window that pops up with fig = gv.d3(g) followed by fig.display().

Add text for different part of line chart plot in plotly python

I draw a figure using plotly (python) as shown in below.
Now my aim is to show all points in same color but add different text for each colored part from this figure. For example, for the blue part I want to add the text AAA and for the red part BBB. How to do that in plotly?
I have simulated data with features that will generate a graph similar to one you have shown
there are three ways to add labels
labels against traces in legend
as additional scatter plots with mode="text"
as annotations on the figure
All three of these are demonstrated below. It does assume you have a working knowledge of pandas
import plotly.express as px
import plotly.graph_objects as go
import pandas as pd
import numpy as np
df = pd.DataFrame({"AAA":np.concatenate([np.random.uniform(1,5,20), np.full(20,np.nan)]),
"BBB":np.concatenate([np.full(20,np.nan), np.random.uniform(1,5,20), ])})
# create two traces, where traces are in legend to label AAA & BBB
fig = px.scatter(df, x=df.index, y=["AAA","BBB"]).update_traces(mode="lines+markers")
# additionally create text trace, that are last AAA & BBB
lastAAA = df.loc[~df["AAA"].isna()].iloc[-1]
lastBBB = df.loc[~df["BBB"].isna()].iloc[-1]
fig.add_trace(go.Scatter(x=[lastAAA.name], y=[lastAAA["AAA"]], text="AAA", mode="text", showlegend=False))
fig.add_trace(go.Scatter(x=[lastBBB.name], y=[lastBBB["BBB"]], text="BBB", mode="text", showlegend=False))
# additionally add annotations
fig.add_annotation(x=lastAAA.name, y=lastAAA["AAA"], text="AAA")
fig.add_annotation(x=lastBBB.name, y=lastBBB["BBB"], text="BBB")

How can I get a graph of graphs to display in Sage?

I am working in SageMathCloud and have the following code:
import networkx
import matplotlib.pyplot as plt
test5 = networkx.Graph()
example = graphs.BuckyBall
test5.add_node(example)
networkx.draw(test5)
plt.show()
and from what I read, should display a graph with a single vertex that has a graph inside of it, like this picture from this article. However, all it shows is a single vertex with nothing inside of it as shown: Is there any way to display the graph to look like the 1st picture, where the graphs (as vertices) are shown?

Why doesn't BokehJS show in a rendered Jupyter/IPython notebook on GitHub?

I have the following code in a Jupyter notebook:
import numpy as np
from bokeh.plotting import figure, show
from bokeh.io import output_notebook
N = 4000
x = np.random.random(size=N) * 100
x = np.random.random(size=N) * 100
radii = np.random.random(size=N) * 1.5
colors = ["#%02x%02x%02x" % (r, g, 150) for r, g in zip(np.floor(50+2*x), np.floor(30+2*y))]
output_notebook()
# Loading BokehJS ...
p = figure()
p.circle(x, y, radius=radii, fill_color=colors, fill_alpha=0.6, line_color=None)
show(p)
However, it does not show any plot or graphics; it simply is stuck on "Loading BokehJS".
In principle, this should work with nbviewer, as rendered notebooks are stripped of all Javascript on GitHub (I think?). In my experience however, it doesn't.
GitHub scrubs all JavaScript from all Jupyter notebooks before rendering them (presumably for security reasons). Bokeh requires JavaScript code from the client library BokehJS in order to render or do anything at all. Given this, I would not expect Bokeh plots in Jupyter notebooks to ever work on GitHub, unfortunately.
I would very much like for it to be workable, but it is entirely outside our control. I have reached out to GitHub asking for an option to disable rendering entirely for notebooks in a repo, on the reasoning that "not rendering at all" is preferable to "rendering but looking broken" but have not heard back from them.
Note that nbviewer does not strip JavaScript, which is why all the notebooks at the Bokeh nbviewer.org gallery show up just fine.

ipython notebook read multiple images and display in CELL

How do I do the above ? This is my code but it doesn't work nothing is displayed
from PIL import Image
import glob
image_list = []
for filename in glob.glob('<my directory>.pgm'):
im=Image.open(filename)
image_list.append(im)
import matplotlib.pyplot as plt
for i in range(10):
plt.figure()
plt.imshow(image_list[i])
I would like it to be displayed in the cell
If you're interested in a much simpler and faster way of displaying images I recommend IPyPlot package:
import ipyplot
ipyplot.plot_images(images_list, max_images=20, img_width=150)
It's capable of displaying hundreds of images in a grid-like format within just 60-70ms
You would get a plot similar to this:
In your case, you should add %matplotlib inlinebefore your code and make sure that after plt.imshow(images_list) you add plt.show() as well so matplotlib renders your images.