How to load large images in PowerBi - powerbi
I want to load pictures in PowerBi, problem is that pictures are a bit bigger than 32kb so it's showing just a part of the picture.
Is there some quick way to go around PowerBi limitation and display entire picture?
I fetched pictures from activite directory, then I converted binary file to text in order to set them as a picture (using this formula : data:image/jpeg;base64)
There is a great article by Chriss Webb, Storing Large Images In Power BI Datasets, from which I will copy the essentials here, in case the original article is not available.
Quote from Chriss Webb's article
The maximum length of a text value that the Power Query engine can load into a single cell in a table in a dataset is 32766 characters – any more than that and the text will be silently truncated. To work around this, what you need to do is to split the text representation of the image up into multiple smaller text values stored across multiple rows, each of which is less than the 32766 character limit, and then reassemble them in a DAX measure after the data has been loaded.
Splitting the text up in M is actually not that hard, but it is hard to do efficiently. Here’s an example of an M query that reads all the data from all of the files in the folder above and returns a table:
let
//Get list of files in folder
Source = Folder.Files("C:\Users\Chris\Documents\PQ Pics"),
//Remove unnecessary columns
RemoveOtherColumns = Table.SelectColumns(Source,{"Content", "Name"}),
//Creates Splitter function
SplitTextFunction = Splitter.SplitTextByRepeatedLengths(30000),
//Converts table of files to list
ListInput = Table.ToRows(RemoveOtherColumns),
//Function to convert binary of photo to multiple
//text values
ConvertOneFile = (InputRow as list) =>
let
BinaryIn = InputRow{0},
FileName = InputRow{1},
BinaryText = Binary.ToText(BinaryIn, BinaryEncoding.Base64),
SplitUpText = SplitTextFunction(BinaryText),
AddFileName = List.Transform(SplitUpText, each {FileName,_})
in
AddFileName,
//Loops over all photos and calls the above function
ConvertAllFiles = List.Transform(ListInput, each ConvertOneFile(_)),
//Combines lists together
CombineLists = List.Combine(ConvertAllFiles),
//Converts results to table
ToTable = #table(type table[Name=text,Pic=text],CombineLists),
//Adds index column to output table
AddIndexColumn = Table.AddIndexColumn(ToTable, "Index", 0, 1)
in
AddIndexColumn
Here’s what the query above returns:
The Pic column contains the split text values, each of which are less than the 32766 character limit, so when this table is loaded into Power BI no truncation occurs. The index column is necessary because without it we won’t be able to recombine all the split values in the correct order.
The only thing left to do is to create a measure that uses the DAX ConcatenateX() function to concatenate all of the pieces of text back into a single value, like so:
Display Image =
IF(
HASONEVALUE('PQ Pics'[Name]),
"data:image/jpeg;base64, " &
CONCATENATEX(
'PQ Pics',
'PQ Pics'[Pic],
,
'PQ Pics'[Index],
ASC)
)
…set the data category of this measure to be “Image URL”:
…and then display the value of the image in a report:
Storing images directly in Power BI is not the best option as using the convert to base64 method you'll be limited to 32KB in size. If possible it would be best to extract the images, and place them in a Azure Blob Store (or other accessible store) and reference them from there. You can use the datatype Image URL to show in a table, or the HTML viewer custom visual to show the image via a url. You'll have to use Power BI to get the list of images in Blob Storage, but if the image name is the same you could link that table to your dataset.
This worked well except:
Image type is hard-coded
Version 2021-07 Desktop doesn't have ImageURL visualization.
Also Card, MultiCard and two free visualizations, Chiclet Browser and Image Grid, but none of these showed my PNG image. Perhaps because it is not JPEG? Image meta data should be correct.
So I managed to use show a miniature picture in a table.
Related
PowerBi Dax - Create a Measure that ignores applied filters and display in barchart
In my data I have two columns of date - claim registration date and resolved date. My report is using resolved date as a slicer filter. I would like to build a bar chart showing registered claims by client segments. I have tried several approaches and functions but they all return single count value. What I want is actual counted values for each type. BySegmentRegistered = CALCULATE(COUNT(claims_data[client_id]),claims_data[reg_date].[MonthNo] == MONTH(SELECTEDVALUE(DateTable[MonthYear])),ALL(claims_data)) BySegmentRegistered = CALCULATE(COUNT(claims_data[client_id]),FILTER(ALL(claims_data),claims_data[reg_date].[MonthNo] == MONTH(SELECTEDVALUE(DateTable[MonthYear])))) I have tried above code and several other iterations but they all return single value across all client_segments. If I simply do COUNT(claims_data[client_id]) than it displays count by each segment but date is wrong, hence it doesnt work for me. Any ideas? EDIT: I just tried this and it works. BySegmentRegistered = CALCULATE(COUNT(claims_data[cliend_id]), claims_data[reg_date].[MonthNo] == MONTH(SELECTEDVALUE(DateTable[MonthYear])), REMOVEFILTERS(DateTable[MonthYear]))
Conditionally format a table based on average of dataset, but adhering to slicer selections
I have a simple CSV data set such as this. ID,MainCategory,SubCategory,Type,Value 1,E,E1,Demo,5 2,N,N3,Install,2 3,E,E1,Demo,4 4,E,E2,Install,7 5,D,D1,Install,3 6,S,S2,PM,4 7,N,N2,Install,7 8,N,N2,Demo,1 9,E,E2,Demo,2 10,D,D2,Install,6 11,D,D3,PM,4 12,S,S1,PM,8 13,N,N1,Install,5 14,S,S3,Install,8 15,S,S1,Demo,9 16,E,E3,Demo,5 17,N,N2,Install,3 18,E,E2,PM,6 19,D,D2,PM,6 20,N,N3,Demo,6 21,S,S2,Demo,7 22,E,E3,Install,2 23,S,S1,Install,4 24,S,S2,PM,8 25,D,D1,Install,5 In my Power BI Desktop, I'd like to load this into a table, and conditionally format the Value column based on whether the value in each row is greater than or less than the average for the currently selected data set. For instance, the average of Value considering the entire table is 5.08, so if there are no filters applied (as in, all my slicers are set to select nothing), I'd like all rows whose Value is 6 or more to be background colored in one color, and the others in another color. For this, I created two measures like so: AvgOfVal = DIVIDE( SUM(G2G[Value]), COUNTA(G2G[ID]) ) BGColor = IF(SUM(G2G[Value]) > [AvgOfVal], "Light Pink", "Light Blue") Then I tried to apply the BGColor measure for conditionally formatting the background, but this doesn't work as expected, and instead produces the result below. I realize that this is due to the fact that the measure is calculated per row, so when conditional formatting is applied, as seen in the AvgOfVal column in the table, it calculates average per row instead of for the entire data set. How can I calculate a measure that takes into account the entire data set (considering slicers), and do the conditional formatting as I need. Please keep in mind that if a user were to select a slicer filter (say, MainCategory = D), then I want the conditional formatting to reflect this. So in this case, given that AvgOfVal = 4.80 for MainCategory = D entries, I'd like all rows whose Value >= 5 to be in one color, and others in another color.
I realize that this is due to the fact that the measure is calculated per row Yes. The key is understanding how that happens. When the measure is calculated a "context transition" happens and the current row is added to the filter context. So what you want is a calculation that removes the row filter that was added in the context transition. So you need ALLSELECTED(), which does precisely that. eg AvgOvVAl = CALCULATE( AVERAGE('data'[Value]), ALLSELECTED() ) Removing the "innermost" filter which in this case is the filter on the row, but leaving all other filters, ie filters added on the report, page, visual, or filters coming from interactions with other visuals like slicers.
Adding label in AutoML for text classification
I am trying to create a text dataset in a Pipeline for a text classification but I believe I am doing it the wrong way or at least I don't get it. The csv passing only contains two columns message and label which is true or false. Inside my pipeline I am creating dataset like this which I am not very sure how dataset is recognizing that column label is the independent variable. dataset = gcp_aip.TextDatasetCreateOp( project = project # my project id, display_name = display_name # reference name, gcs_source = src_uris # path to my data in gcs, import_schema_uri = aiplatform.schema.dataset.ioformat.text.single_label_classification, ) once created the dataset, i do training like this within the Pipeline # training model = gcp_aip.AutoMLTextTrainingJobRunOp( project = project, display_name = display_name, prediction_type = "classification", multi_label = False, dataset = dataset.outputs["dataset"], ) Not sure if creation and training is doing correctly since I never specified that label is my label column and needs to use message as a feature. In vertex ai the dataset created look like this But in my training section the results from the AutML, looks like this, dont know why, label with 0% is there, which makes me doubt about the insertion of the data
In preparation of CSV file, you don't need to specify which column is the feature and the label. Vertex AI's AutoML automatically reads the first column as the feature and the second column as the label. You may refer to this documentation for more details in preparation of CSV data. Below is sample CSV file, all values under first column(column A) are detected to be the feature and all values under second column(column B) are the labels. You might need to check your CSV file and search for the word "label" on your second column and replace it with either "True" or "False" since based on your given data, you are only trying to have 2 labels which are "True" and "False". In addition, if you find the word "label" on your 2nd column and it doesn't have a value on its first column, then you just need to just remove the word "label". In your provided screenshot here, there is a 1 count for the word "label", which means there is a "label" value existing on the 2nd column of your CSV data.
How to filter based on the URL of an image in Google Sheets?
I'm trying to create a filter view in Google Sheets that will only show certain rows of the spreadsheet based on the last few characters of the URL of the images that are inserted in every row. For example, most rows have an image that is simply named "image1.png", "image2.png", "image3.png", etc, but every once in a while there'll be a row where the image is named "image63_s.png", "image176_s.png", "image271_s.png", etc. What I'd like to do is create a filter view that will only show rows where the name of the image in the URL ends with "_s". EDIT: The images are inserted into the sheet with the formula =IMAGE("https://www.example.com/site/image1.png"), so I don't think regex can work here.
use custom formula: =REGEXMATCH(A1, ".*_s.png$") update: =REGEXMATCH(FORMULATEXT(A1), ".*_s.png.*") or as suggested have a hidden helper column of urls
power query Shifting row of cells to the right
I've imported a pdf file into power query. On a few of rows, the data has shifted 1 cell to the right and one those rows they are now not in the correct column. I can fix it in Excel, but is there a way to fix it in power query?
I ran into a similar challenge where the header row was displaced by one column when the exporting PDF content output to CSV. I used the following strategy in Power Query: Convert the affected row/record to a list. Split it and reassemble it, i.e., sort it in the correct order. Convert it back to a record and insert it back into the table. Remove the old record It looks something like this: let Source = Excel.CurrentWorkbook(){[Name="tblShiftLeft"]}[Content], // Fetches the table/range containing the row data that needs to be shifted. #"Shifted Headers" = List.Combine({List.RemoveFirstN(Record.ToList(Source{0}),1), {""}}), // converts to list, splits, and reassembles #"New Headers" = Record.FromList(#"Shifted Headers",Table.ColumnNames(Source)), // Creates a record from the list using the column names #"New Headers Added" = Table.InsertRows(Source,1,{#"New Headers"}), // Insert the newly poisitioned header row. #"Headers Adjusted" = Table.RemoveRows(#"New Headers Added",0) // Remove the old row in #"Headers Adjusted" Hope this helps,