Case: multi-line by \n.
I think the same modification to bokeh text required.
from bokeh.io import output_file, show
from bokeh.models import Label
from bokeh.plotting import figure
output_file("text.html")
p = figure(x_range=(0, 5))
p.text(x=[1,2,3], y = [0,0,0], text=['hello\nworld!', 'hello\nworld!', 'hello\nworld!'], angle = 0)
label = Label(x=2, y=-0.5,
text='label\nworld',render_mode='css',border_line_alpha=0.5,
background_fill_alpha=0.5)
p.add_layout(label)
show(p)
enter image description here
As of version 0.12.13 multi line text is only supported by the text glyph. If you'd like to request it be added to Label please make a feature request issue on GitHub.
Related
Using Google Colab, I would like to be able to read in some number of image files each of which is at a different url and then display each of them. I got the following code to work but it only displays the first image (no output for the 2nd or error messages) Also, if I add a print statement to the output, then no image display at all. So what's the trick? Thanks.
!pip install pillow
import urllib.request
from PIL import Image
# First Image
imageURL1 = "https://www.example.com/dir/imagefile1.jpg"
imageName1="file1.jpg"
urllib.request.urlretrieve(imageURL1, imageName1)
img1 = Image.open(imageName1)
img1 # this works but only if it is the only output
# Second Image
imageURL2 = "https://www.example.com/dir/imagefile2.jpg"
imageName2="file2.jpg"
urllib.request.urlretrieve(imageURL2, imageName2)
img2 = Image.open(imageName2)
img2 # does not display
#print("x") # a print kills the image display
Found an answer that works. Use IPython to display the image. It works with multiple images and the print() works as well.
!pip install pillow
import urllib.request
from PIL import Image
from IPython.display import display
# First Image
imageURL1 = "https://www.example.com/dir/imagefile1.jpg"
imageName1="file1.jpg"
urllib.request.urlretrieve(imageURL1, imageName1)
img1 = Image.open(imageName1)
display(img1) # this works but only if it is the only output
print("AND THE PRINT WORKS")
# Second Image
imageURL2 = "https://www.example.com/dir/imagefile2.jpg"
imageName2="file2.jpg"
urllib.request.urlretrieve(imageURL2, imageName2)
img2 = Image.open(imageName2)
display(img2)
I'm using pandas, geopandas, and cartopy to make spatial plots for data points.
Everything works fine, except for when I try to add color bar.
Below is my code and the error. Any help is appreciated.
fig = plt.figure()
ax = plt.axes(projection=ccrs.PlateCarree())
reader = shpreader.Reader('countyl010g.shp')
counties = list(reader.geometries())
COUNTIES = cfeature.ShapelyFeature(counties, ccrs.PlateCarree())
ax.add_feature(COUNTIES, facecolor='none', edgecolor='gray')
ax.coastlines()
ax.add_feature(cartopy.feature.STATES)
dp=pd.read_csv('Arash.csv',index_col=False)
def remove_minutes(state):
state=datetime.datetime.strptime(state, '%Y-%m-%d %H:%M:%S')
state= state.replace(minute=0)
return state
dp['TIMESTAMP']=dp['TIMESTAMP'].apply(remove_minutes)
dp.set_index(['TIMESTAMP'], inplace=True)
dp= dp[dp.index.day == 28]
dp['coordinates'] = dp[['Longitude', 'Latitude']].values.tolist()
dp['coordinates'] = dp['coordinates'].apply(Point)
dp = gpd.GeoDataFrame(dp, geometry='coordinates')
ac=dp.plot(ax=ax,column='CO_CMAQ',markersize=0.05,cmap='turbo')
ax.set_xlim(-119,-117)
ax.set_ylim(33.5,34.5)
fig.colorbar(ac,ax=ax)
And here is the error:
File "C:\Python-practice\GHG\spatial_plot_mobile.py", line 102, in
fig.colorbar(ac,ax=ax)
File
"C:\Users\akash\anaconda3\lib\site-packages\matplotlib\figure.py",
line 2343, in colorbar cb = cbar.colorbar_factory(cax, mappable,
**cb_kw)
File
"C:\Users\akash\anaconda3\lib\site-packages\matplotlib\colorbar.py",
line 1734, in colorbar_factory cb = Colorbar(cax, mappable, **kwargs)
File
"C:\Users\akash\anaconda3\lib\site-packages\matplotlib\colorbar.py",
line 1202, in init
if mappable.get_array() is not None: AttributeError: 'GeoAxesSubplot'
object has no attribute 'get_array'
Thank you again,
Old question, but I landed on it because I had an analogous error, so in case it helps anyone else in future:
The problem is that ac here is a GeoAxesSubplot object within a Matplotlib figure. When Matplotlib is given fig.colorbar(ac,ax=ax), it doesn't know what to do with ac.
As per the Geopandas documentation, the information about the colorbar needs to go into the Geopandas .plot() itself, so that the relevant line above would look something like:
ac=dp.plot(ax=ax,column='CO_CMAQ',markersize=0.05,cmap='turbo',
legend=True, legend_kwds={'label':"",'orientation':""})
with the legend_kwds filled in as desired, e.g. orientation="horizontal".
More advice on modifying Geopandas colorbars here.
New user with Altair, trying to sort NFL player names by the "Player COUNT" field. The data is pre-aggregated to show each playername only once, with the count associated to it.
Sorting the y axis which is 'Player Name' based on the count in -x works fine until I add color, which i want to be a discrete dimension. Any idea what needs to be done to prevent color from overriding the sort on Y?
import altair as alt
import pandas as pd
source = pd.read_csv("C:/Users/abcdef/Documents/user_players.csv", encoding = "ISO-8859-1")
print(source.head())
bars = alt.Chart(source).mark_bar().encode(
x=alt.X('Player COUNT:Q'),#,scale=alt.Scale(domain=(1,5),clamp=True)),
y=alt.Y('Player Name:N',sort='-x')
#y=alt.Y('Player Name:N',sort=alt.SortField(field="sort_order",op="distinct",order='descending')),
,color='Ownership Percentile:O'
).transform_filter(
alt.FieldLTEPredicate(field='player_row', lte=50)
)
text = bars.mark_text(
align='left',
baseline='middle',
dx=3 # Nudges text to right so it doesn't appear on top of the bar
).encode(
text='Player COUNT:Q'
)
(bars + text).properties(width =400,height=900)#.interactive()
This looks like a bug in the Vega-Lite renderer. You can work around it by using an EncodingSortField with an explicit op in place of the -x shorthand:
bars = alt.Chart(source).mark_bar().encode(
x=alt.X('Player COUNT:Q'),#,scale=alt.Scale(domain=(1,5),clamp=True)),
y=alt.Y('Player Name:N',sort=alt.EncodingSortField(field="Player COUNT", order='descending', op='max')),
color='Ownership Percentile:O'
).transform_filter(
alt.FieldLTEPredicate(field='player_row', lte=50)
)
lm = sns.lmplot(x='early_mean_zscores', y='late_mean_zscores', col='cat', data=combo)
fig = lm.fig
fig.suptitle("Improvement from Early to Late assignments")
a1 = fig.axes[1]
a1.title("adsadas")
I would like to set the title of the subplots generated by hand, i.e. not based on the col='cat'. This code, and many permutations of it that I have tried don't seem to work.
I don't understand the timing of when the plot is fixed and displayed. Is it on the first line, lm = ... in which case it's not surprising that I cannot, retroactively change the title.
I could use some help on both fixing the code, and a clarification on the sequencing and theory of what is going wrong.
The command to set a title is ax.set_title(). Using that, the code should work as expected.
A minimal example:
import matplotlib.pyplot as plt
import seaborn as sns
tips = sns.load_dataset("tips")
lm = sns.lmplot(x="total_bill", y="tip", col="smoker", data=tips)
fig = lm.fig
fig.suptitle("Custom Super Title")
a1 = fig.axes[1]
a1.set_title("Custom Title")
plt.show()
depending on what you need, you could just use:
lm = sns.lmplot(x="total_bill", y="tip", col="smoker", data=tips).set_titles("{col_name}") # {col_name} is special parameter of actual column name
I would like to automatically adjust the width of a bokeh DataTable to the size of a screen. But I do not find the right way to do it. This line of code is supposed to work :
data_table = DataTable(source=source, columns=columns, height = 300, sizing_mode = 'scale_width', fit_columns=True)
But it does not. My Datatable keeps the same width.
Does anyone know how to solve this problem ?
Thank you.
I'm afraid it's not possible with the current implementation of DataTable - if you don't specify an explicit width in pixels, the width will be set to 600px.
You're welcome to create a feature request on Bokeh's GitHub.
As of 2.2.3 and likely earlier you can use sizing_mode:
import pandas as pd, numpy as np, random, string
from bokeh.models import ColumnDataSource, DataTable, TableColumn
from bokeh.plotting import show
df = pd.DataFrame(np.random.randint(0,100,size=(100, 12)), columns=[(random.randint(1,30) * random.choice(string.ascii_uppercase)) for col in range(12)])
data_table = DataTable(columns = [TableColumn(field=c, title=c) for c in df.columns], sizing_mode='stretch_width', source = ColumnDataSource(df))
show(data_table)